@eaera-com/cms-sdk 0.1.92 → 0.1.94
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/dist/chunks/chats-F9H8sza4.js +109 -0
- package/dist/chunks/client-B7fm_H2u.js +184 -0
- package/dist/chunks/connection-DGlB8IZD.js +108 -0
- package/dist/chunks/qwenpaw.constant-BwpRhdCV.js +24 -0
- package/dist/common/constants/index.d.ts +1 -0
- package/dist/common/constants/index.d.ts.map +1 -1
- package/dist/common/constants/qwenpaw.constant.d.ts +46 -0
- package/dist/common/constants/qwenpaw.constant.d.ts.map +1 -0
- package/dist/composables/useQwenpawChat.d.ts +240 -0
- package/dist/composables/useQwenpawChat.d.ts.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +390 -4
- package/dist/nuxt.d.ts.map +1 -1
- package/dist/nuxt.js +10 -1
- package/dist/server/ai/qwenpaw/chat/stop.post.js +25 -0
- package/dist/server/ai/qwenpaw/chat.post.js +61 -0
- package/dist/server/ai/qwenpaw/chats-id.delete.js +18 -0
- package/dist/server/ai/qwenpaw/chats.get.js +33 -0
- package/dist/server/ai/qwenpaw/history.get.js +16 -0
- package/dist/server/ai/qwenpaw/session.get.js +14 -0
- package/dist/server/ai/qwenpaw/session.post.js +31 -0
- package/dist/server/ai/qwenpaw/upload.post.js +40 -0
- package/dist/services/qwenpaw/chats.d.ts +25 -0
- package/dist/services/qwenpaw/chats.d.ts.map +1 -0
- package/dist/services/qwenpaw/client.d.ts +42 -0
- package/dist/services/qwenpaw/client.d.ts.map +1 -0
- package/dist/services/qwenpaw/qwenpaw.type.d.ts +236 -0
- package/dist/services/qwenpaw/qwenpaw.type.d.ts.map +1 -0
- package/dist/services/qwenpaw/stream.d.ts +16 -0
- package/dist/services/qwenpaw/stream.d.ts.map +1 -0
- package/dist/stores/index.d.ts +1 -0
- package/dist/stores/index.d.ts.map +1 -1
- package/dist/stores/qwenpawChat.d.ts +219 -0
- package/dist/stores/qwenpawChat.d.ts.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { createError } from 'h3';
|
|
2
|
+
import { ofetch } from 'ofetch';
|
|
3
|
+
import { d as QWENPAW_LIST_TIMEOUT_MS, e as QWENPAW_DEFAULT_AGENT_ID, f as QWENPAW_MAX_HISTORY_TURNS } from './qwenpaw.constant-BwpRhdCV.js';
|
|
4
|
+
|
|
5
|
+
const chatsHeaders = (connection, extra = {}) => ({
|
|
6
|
+
accept: "application/json",
|
|
7
|
+
"x-agent-id": connection.agentId || QWENPAW_DEFAULT_AGENT_ID,
|
|
8
|
+
...extra
|
|
9
|
+
});
|
|
10
|
+
const chatsUrl = (baseUrl, path) => `${baseUrl.replace(/\/+$/, "")}${path}`;
|
|
11
|
+
const throwOnAuthFailure = (error) => {
|
|
12
|
+
const err = error;
|
|
13
|
+
const status = err?.status ?? err?.statusCode ?? err?.response?.status ?? 0;
|
|
14
|
+
if (status === 401 || status === 403) {
|
|
15
|
+
throw createError({ statusCode: status, message: "The AI session is no longer valid." });
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
const listQwenpawChats = async (connection) => {
|
|
19
|
+
if (!connection.baseUrl) return [];
|
|
20
|
+
try {
|
|
21
|
+
const res = await ofetch(chatsUrl(connection.baseUrl, "/api/chats"), {
|
|
22
|
+
params: { archived: false, include_app_owned: false },
|
|
23
|
+
headers: chatsHeaders(connection),
|
|
24
|
+
timeout: QWENPAW_LIST_TIMEOUT_MS
|
|
25
|
+
});
|
|
26
|
+
return Array.isArray(res) ? res : [];
|
|
27
|
+
} catch (error) {
|
|
28
|
+
throwOnAuthFailure(error);
|
|
29
|
+
console.error("qwenpaw-chats", error);
|
|
30
|
+
return [];
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
const listQwenpawGroups = async (connection) => {
|
|
34
|
+
if (!connection.baseUrl) return [];
|
|
35
|
+
try {
|
|
36
|
+
const res = await ofetch(chatsUrl(connection.baseUrl, "/api/chats/groups"), {
|
|
37
|
+
headers: chatsHeaders(connection),
|
|
38
|
+
timeout: QWENPAW_LIST_TIMEOUT_MS
|
|
39
|
+
});
|
|
40
|
+
return Array.isArray(res) ? res : [];
|
|
41
|
+
} catch (error) {
|
|
42
|
+
throwOnAuthFailure(error);
|
|
43
|
+
console.error("qwenpaw-groups", error);
|
|
44
|
+
return [];
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
const deleteQwenpawChat = async (connection, chatId) => {
|
|
48
|
+
if (!connection.baseUrl || !chatId) return false;
|
|
49
|
+
try {
|
|
50
|
+
await ofetch(chatsUrl(connection.baseUrl, `/api/chats/${encodeURIComponent(chatId)}`), {
|
|
51
|
+
method: "DELETE",
|
|
52
|
+
headers: chatsHeaders(connection),
|
|
53
|
+
timeout: QWENPAW_LIST_TIMEOUT_MS
|
|
54
|
+
});
|
|
55
|
+
return true;
|
|
56
|
+
} catch (error) {
|
|
57
|
+
console.error("qwenpaw-chat-delete", error);
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
const getQwenpawChatMessages = async (connection, chatId) => {
|
|
62
|
+
if (!connection.baseUrl || !chatId) return [];
|
|
63
|
+
try {
|
|
64
|
+
const res = await ofetch(
|
|
65
|
+
chatsUrl(connection.baseUrl, `/api/chats/${encodeURIComponent(chatId)}`),
|
|
66
|
+
{
|
|
67
|
+
params: { include_app_owned: false },
|
|
68
|
+
headers: chatsHeaders(connection),
|
|
69
|
+
timeout: QWENPAW_LIST_TIMEOUT_MS
|
|
70
|
+
}
|
|
71
|
+
);
|
|
72
|
+
return Array.isArray(res?.messages) ? res.messages : [];
|
|
73
|
+
} catch (error) {
|
|
74
|
+
throwOnAuthFailure(error);
|
|
75
|
+
console.error("qwenpaw-chat-history", error);
|
|
76
|
+
return [];
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
const messagesToTurns = (messages) => {
|
|
80
|
+
const turns = [];
|
|
81
|
+
for (const message of messages) {
|
|
82
|
+
const role = message.role === "user" ? "user" : "assistant";
|
|
83
|
+
if (role === "assistant" && message.type !== "message") continue;
|
|
84
|
+
const text = (message.content ?? []).filter((part) => part?.type === "text" && typeof part.text === "string").map((part) => part.text).join("").trim();
|
|
85
|
+
if (!text) continue;
|
|
86
|
+
const tsRaw = message.metadata?.timestamp;
|
|
87
|
+
const ts = tsRaw ? Date.parse(tsRaw) : NaN;
|
|
88
|
+
turns.push({
|
|
89
|
+
id: message.id ?? `t-${turns.length}`,
|
|
90
|
+
role,
|
|
91
|
+
text,
|
|
92
|
+
...Number.isFinite(ts) ? { ts } : {}
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
return turns.length > QWENPAW_MAX_HISTORY_TURNS ? turns.slice(-QWENPAW_MAX_HISTORY_TURNS) : turns;
|
|
96
|
+
};
|
|
97
|
+
const extractChatModel = (messages) => {
|
|
98
|
+
for (let i = messages.length - 1; i >= 0; i -= 1) {
|
|
99
|
+
const model = messages[i]?.metadata?.qwenpaw_turn_usage?.usage?.model_name;
|
|
100
|
+
if (typeof model === "string" && model) return model;
|
|
101
|
+
}
|
|
102
|
+
return "";
|
|
103
|
+
};
|
|
104
|
+
const fetchChatHistory = async (connection, chatId) => {
|
|
105
|
+
const messages = await getQwenpawChatMessages(connection, chatId);
|
|
106
|
+
return { turns: messagesToTurns(messages), model: extractChatModel(messages) };
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
export { listQwenpawGroups as a, deleteQwenpawChat as d, extractChatModel as e, fetchChatHistory as f, getQwenpawChatMessages as g, listQwenpawChats as l, messagesToTurns as m };
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
import { h as QWENPAW_CHANNEL, i as QWENPAW_CHAT_TIMEOUT_MS, j as QWENPAW_STOP_TIMEOUT_MS, k as QWENPAW_UPLOAD_TIMEOUT_MS } from './qwenpaw.constant-BwpRhdCV.js';
|
|
2
|
+
import { createError } from 'h3';
|
|
3
|
+
|
|
4
|
+
const buildConsoleChatBody = (target, text, files = []) => ({
|
|
5
|
+
input: [
|
|
6
|
+
{
|
|
7
|
+
role: "user",
|
|
8
|
+
type: "message",
|
|
9
|
+
content: [
|
|
10
|
+
...files.map((file) => ({
|
|
11
|
+
type: "file",
|
|
12
|
+
file_url: file.url,
|
|
13
|
+
file_name: file.name,
|
|
14
|
+
...file.size !== void 0 ? { file_size: file.size } : {},
|
|
15
|
+
status: "created"
|
|
16
|
+
})),
|
|
17
|
+
...text ? [{ type: "text", text, status: "created" }] : []
|
|
18
|
+
],
|
|
19
|
+
metadata: {
|
|
20
|
+
qwenpaw_client_message_id: `${Date.now()}-${Math.random().toString(36).slice(2)}`
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
],
|
|
24
|
+
session_id: target.sessionId,
|
|
25
|
+
user_id: target.userId,
|
|
26
|
+
channel: QWENPAW_CHANNEL,
|
|
27
|
+
request_context: {
|
|
28
|
+
source: "console_chat",
|
|
29
|
+
agent_id: target.agentId,
|
|
30
|
+
chat_id: target.sessionId,
|
|
31
|
+
sdk_session_id: target.sessionId,
|
|
32
|
+
approval_level: "AUTO"
|
|
33
|
+
},
|
|
34
|
+
stream: true
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
class QwenpawConfigError extends Error {
|
|
38
|
+
}
|
|
39
|
+
class QwenpawUpstreamError extends Error {
|
|
40
|
+
constructor(status, message) {
|
|
41
|
+
super(message);
|
|
42
|
+
this.status = status;
|
|
43
|
+
}
|
|
44
|
+
status;
|
|
45
|
+
}
|
|
46
|
+
const resolveTargetBase = (config, target) => {
|
|
47
|
+
const baseUrl = (target.baseUrl || config.baseUrl).replace(/\/+$/, "");
|
|
48
|
+
if (!baseUrl) {
|
|
49
|
+
throw new QwenpawConfigError("QwenPaw URL is not configured (no per-user or server default).");
|
|
50
|
+
}
|
|
51
|
+
const agentId = target.agentId || config.agentId;
|
|
52
|
+
if (!agentId) {
|
|
53
|
+
throw new QwenpawConfigError("No QwenPaw agent id configured for this workspace.");
|
|
54
|
+
}
|
|
55
|
+
return { baseUrl, agentId };
|
|
56
|
+
};
|
|
57
|
+
const linkAbort = (signal, timeoutMs) => {
|
|
58
|
+
const controller = new AbortController();
|
|
59
|
+
const timeout = setTimeout(() => controller.abort(), timeoutMs);
|
|
60
|
+
signal?.addEventListener("abort", () => controller.abort(), { once: true });
|
|
61
|
+
return { controller, cleanup: () => clearTimeout(timeout) };
|
|
62
|
+
};
|
|
63
|
+
const postConsoleChatError = (error) => {
|
|
64
|
+
if (error instanceof QwenpawConfigError) {
|
|
65
|
+
return createError({ statusCode: 503, message: error.message });
|
|
66
|
+
}
|
|
67
|
+
if (error instanceof QwenpawUpstreamError) {
|
|
68
|
+
return createError({
|
|
69
|
+
statusCode: error.status,
|
|
70
|
+
statusMessage: error.message,
|
|
71
|
+
message: error.message
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
console.error("qwenpaw-chat", error);
|
|
75
|
+
return createError({ statusCode: 502, message: "QwenPaw is unreachable." });
|
|
76
|
+
};
|
|
77
|
+
const qwenpawChat = async (options) => {
|
|
78
|
+
const { baseUrl, agentId } = resolveTargetBase(options.config, options.target);
|
|
79
|
+
if (!options.target.sessionId) {
|
|
80
|
+
throw new QwenpawConfigError("No QwenPaw session id on this workspace.");
|
|
81
|
+
}
|
|
82
|
+
const body = buildConsoleChatBody(options.target, options.text, options.files ?? []);
|
|
83
|
+
const { controller, cleanup } = linkAbort(
|
|
84
|
+
options.signal,
|
|
85
|
+
options.timeoutMs ?? QWENPAW_CHAT_TIMEOUT_MS
|
|
86
|
+
);
|
|
87
|
+
try {
|
|
88
|
+
const response = await fetch(`${baseUrl}/api/console/chat`, {
|
|
89
|
+
method: "POST",
|
|
90
|
+
headers: {
|
|
91
|
+
"content-type": "application/json",
|
|
92
|
+
"x-agent-id": agentId,
|
|
93
|
+
accept: "text/event-stream"
|
|
94
|
+
},
|
|
95
|
+
body: JSON.stringify(body),
|
|
96
|
+
signal: controller.signal
|
|
97
|
+
});
|
|
98
|
+
if (!response.ok || !response.body) {
|
|
99
|
+
const detail = await response.text().catch(() => "");
|
|
100
|
+
console.error("qwenpaw-chat", response.status, detail.slice(0, 500));
|
|
101
|
+
throw new QwenpawUpstreamError(
|
|
102
|
+
response.status,
|
|
103
|
+
response.status === 404 ? "QwenPaw agent not found." : response.status === 401 || response.status === 403 ? "QwenPaw rejected the credentials." : "QwenPaw chat request failed."
|
|
104
|
+
);
|
|
105
|
+
}
|
|
106
|
+
return response;
|
|
107
|
+
} catch (error) {
|
|
108
|
+
if (error instanceof QwenpawUpstreamError || error instanceof QwenpawConfigError) throw error;
|
|
109
|
+
if (error instanceof Error && error.name === "AbortError") {
|
|
110
|
+
throw new QwenpawUpstreamError(504, "QwenPaw did not respond in time.");
|
|
111
|
+
}
|
|
112
|
+
console.error("qwenpaw-chat", error);
|
|
113
|
+
throw new QwenpawUpstreamError(502, "QwenPaw is unreachable.");
|
|
114
|
+
} finally {
|
|
115
|
+
cleanup();
|
|
116
|
+
}
|
|
117
|
+
};
|
|
118
|
+
const qwenpawUpload = async (options) => {
|
|
119
|
+
const { baseUrl, agentId } = resolveTargetBase(options.config, options.target);
|
|
120
|
+
const { controller, cleanup } = linkAbort(
|
|
121
|
+
options.signal,
|
|
122
|
+
options.timeoutMs ?? QWENPAW_UPLOAD_TIMEOUT_MS
|
|
123
|
+
);
|
|
124
|
+
try {
|
|
125
|
+
const response = await fetch(`${baseUrl}/api/console/upload`, {
|
|
126
|
+
method: "POST",
|
|
127
|
+
headers: {
|
|
128
|
+
"x-agent-id": agentId
|
|
129
|
+
},
|
|
130
|
+
body: options.form,
|
|
131
|
+
signal: controller.signal
|
|
132
|
+
});
|
|
133
|
+
const payload = await response.json().catch(() => null);
|
|
134
|
+
if (!response.ok || !payload?.url) {
|
|
135
|
+
const detail = typeof payload?.message === "string" ? payload.message : "";
|
|
136
|
+
console.error("qwenpaw-upload", response.status, detail.slice(0, 500));
|
|
137
|
+
throw new QwenpawUpstreamError(
|
|
138
|
+
response.status,
|
|
139
|
+
response.status === 401 || response.status === 403 ? "QwenPaw rejected the credentials." : "QwenPaw rejected the file upload."
|
|
140
|
+
);
|
|
141
|
+
}
|
|
142
|
+
return { url: payload.url, file_name: payload.file_name ?? "", size: payload.size ?? 0 };
|
|
143
|
+
} catch (error) {
|
|
144
|
+
if (error instanceof QwenpawUpstreamError || error instanceof QwenpawConfigError) throw error;
|
|
145
|
+
if (error instanceof Error && error.name === "AbortError") {
|
|
146
|
+
throw new QwenpawUpstreamError(504, "QwenPaw did not respond in time.");
|
|
147
|
+
}
|
|
148
|
+
console.error("qwenpaw-upload", error);
|
|
149
|
+
throw new QwenpawUpstreamError(502, "QwenPaw is unreachable.");
|
|
150
|
+
} finally {
|
|
151
|
+
cleanup();
|
|
152
|
+
}
|
|
153
|
+
};
|
|
154
|
+
const qwenpawStop = async (options) => {
|
|
155
|
+
const { baseUrl, agentId } = resolveTargetBase(options.config, options.target);
|
|
156
|
+
const { controller, cleanup } = linkAbort(
|
|
157
|
+
options.signal,
|
|
158
|
+
options.timeoutMs ?? QWENPAW_STOP_TIMEOUT_MS
|
|
159
|
+
);
|
|
160
|
+
try {
|
|
161
|
+
const response = await fetch(
|
|
162
|
+
`${baseUrl}/api/console/chat/stop?chat_id=${encodeURIComponent(options.sessionId)}`,
|
|
163
|
+
{
|
|
164
|
+
method: "POST",
|
|
165
|
+
headers: {
|
|
166
|
+
"x-agent-id": agentId
|
|
167
|
+
},
|
|
168
|
+
signal: controller.signal
|
|
169
|
+
}
|
|
170
|
+
);
|
|
171
|
+
if (!response.ok) {
|
|
172
|
+
throw new QwenpawUpstreamError(response.status, "QwenPaw rejected the stop request.");
|
|
173
|
+
}
|
|
174
|
+
return await response.json().catch(() => ({ stopped: false }));
|
|
175
|
+
} catch (error) {
|
|
176
|
+
if (error instanceof QwenpawUpstreamError || error instanceof QwenpawConfigError) throw error;
|
|
177
|
+
console.error("qwenpaw-stop", error);
|
|
178
|
+
throw new QwenpawUpstreamError(502, "QwenPaw is unreachable.");
|
|
179
|
+
} finally {
|
|
180
|
+
cleanup();
|
|
181
|
+
}
|
|
182
|
+
};
|
|
183
|
+
|
|
184
|
+
export { QwenpawConfigError as Q, QwenpawUpstreamError as a, buildConsoleChatBody as b, qwenpawStop as c, qwenpawUpload as d, postConsoleChatError as p, qwenpawChat as q };
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { getCookie, createError, setCookie } from 'h3';
|
|
2
|
+
import { ofetch } from 'ofetch';
|
|
3
|
+
import { useRuntimeConfig } from '#imports';
|
|
4
|
+
import { T as TOKEN_STORAGE_KEY } from './storage.constant-CVWam5ls.js';
|
|
5
|
+
import { l as QWENPAW_COOKIE_AGENT_ID, m as QWENPAW_COOKIE_BASE_URL, n as QWENPAW_RUNTIME_CONFIG_KEY, o as QWENPAW_EXCHANGE_ACTION_PATH, p as QWENPAW_EXCHANGE_TIMEOUT_MS, q as QWENPAW_CONFIGURATION_ERROR_CODES, r as QWENPAW_COOKIE_MAX_AGE } from './qwenpaw.constant-BwpRhdCV.js';
|
|
6
|
+
|
|
7
|
+
class QwenpawExchangeError extends Error {
|
|
8
|
+
constructor(code, configurationError, message) {
|
|
9
|
+
super(message);
|
|
10
|
+
this.code = code;
|
|
11
|
+
this.configurationError = configurationError;
|
|
12
|
+
}
|
|
13
|
+
code;
|
|
14
|
+
configurationError;
|
|
15
|
+
}
|
|
16
|
+
const resolveQwenpawServerConfig = (event) => {
|
|
17
|
+
const config = useRuntimeConfig(event);
|
|
18
|
+
const qwenpaw = config[QWENPAW_RUNTIME_CONFIG_KEY] ?? {};
|
|
19
|
+
return {
|
|
20
|
+
baseUrl: String(qwenpaw.baseUrl ?? "").replace(/\/+$/, ""),
|
|
21
|
+
agentId: String(qwenpaw.agentId ?? "")
|
|
22
|
+
};
|
|
23
|
+
};
|
|
24
|
+
const setQwenpawSessionCookies = (event, connection) => {
|
|
25
|
+
const common = {
|
|
26
|
+
httpOnly: true,
|
|
27
|
+
sameSite: "lax",
|
|
28
|
+
path: "/",
|
|
29
|
+
maxAge: QWENPAW_COOKIE_MAX_AGE
|
|
30
|
+
};
|
|
31
|
+
setCookie(event, QWENPAW_COOKIE_BASE_URL, connection.baseUrl, common);
|
|
32
|
+
setCookie(event, QWENPAW_COOKIE_AGENT_ID, connection.agentId, common);
|
|
33
|
+
};
|
|
34
|
+
const resolveQwenpawConnection = (event, overrides = {}) => {
|
|
35
|
+
const config = resolveQwenpawServerConfig(event);
|
|
36
|
+
return {
|
|
37
|
+
baseUrl: overrides.baseUrl || getCookie(event, QWENPAW_COOKIE_BASE_URL) || config.baseUrl,
|
|
38
|
+
agentId: overrides.agentId || getCookie(event, QWENPAW_COOKIE_AGENT_ID) || config.agentId
|
|
39
|
+
};
|
|
40
|
+
};
|
|
41
|
+
const hasQwenpawConnection = (event) => Boolean(resolveQwenpawConnection(event).baseUrl);
|
|
42
|
+
const cmsBackendUrl = (event) => {
|
|
43
|
+
const pub = useRuntimeConfig(event).public ?? {};
|
|
44
|
+
const opts = pub.cmsSdkOptions ?? {};
|
|
45
|
+
return String(pub[opts.endpoints?.cms ?? "cmsUrl"] ?? "").replace(/\/+$/, "");
|
|
46
|
+
};
|
|
47
|
+
const requireCmsSession = (event) => {
|
|
48
|
+
if (!getCookie(event, TOKEN_STORAGE_KEY)) {
|
|
49
|
+
throw createError({ statusCode: 401, message: "Sign in to use the AI chat." });
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
const exchangeQwenpawSession = async (event) => {
|
|
53
|
+
const backend = cmsBackendUrl(event);
|
|
54
|
+
const userToken = getCookie(event, TOKEN_STORAGE_KEY);
|
|
55
|
+
if (!backend || !userToken) {
|
|
56
|
+
throw new QwenpawExchangeError("AI_NOT_AUTHENTICATED", false, "Sign in to use the AI chat.");
|
|
57
|
+
}
|
|
58
|
+
let envelope;
|
|
59
|
+
try {
|
|
60
|
+
envelope = await ofetch(`${backend}${QWENPAW_EXCHANGE_ACTION_PATH}`, {
|
|
61
|
+
method: "POST",
|
|
62
|
+
headers: { authorization: `Bearer ${userToken}`, "content-type": "application/json" },
|
|
63
|
+
body: { params: {} },
|
|
64
|
+
timeout: QWENPAW_EXCHANGE_TIMEOUT_MS
|
|
65
|
+
});
|
|
66
|
+
} catch (error) {
|
|
67
|
+
const status = error?.status ?? error?.statusCode ?? 0;
|
|
68
|
+
if (status === 401) {
|
|
69
|
+
throw new QwenpawExchangeError("AI_NOT_AUTHENTICATED", false, "Sign in to use the AI chat.");
|
|
70
|
+
}
|
|
71
|
+
if (status === 403) {
|
|
72
|
+
throw new QwenpawExchangeError(
|
|
73
|
+
"AI_AGENT_NOT_ASSIGNED",
|
|
74
|
+
true,
|
|
75
|
+
"You have not been assigned a personal AI agent."
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
throw new QwenpawExchangeError(
|
|
79
|
+
"AI_SESSION_EXCHANGE_FAILED",
|
|
80
|
+
false,
|
|
81
|
+
"The AI agent is unreachable."
|
|
82
|
+
);
|
|
83
|
+
}
|
|
84
|
+
if (!envelope?.success || !envelope.output) {
|
|
85
|
+
throw new QwenpawExchangeError(
|
|
86
|
+
"AI_SESSION_EXCHANGE_FAILED",
|
|
87
|
+
false,
|
|
88
|
+
envelope?.error || "The AI session exchange failed."
|
|
89
|
+
);
|
|
90
|
+
}
|
|
91
|
+
const result = envelope.output;
|
|
92
|
+
if (!result.success || !result.agent || !result.session) {
|
|
93
|
+
const code = result.code ?? "AI_SESSION_EXCHANGE_FAILED";
|
|
94
|
+
throw new QwenpawExchangeError(
|
|
95
|
+
code,
|
|
96
|
+
QWENPAW_CONFIGURATION_ERROR_CODES.has(code),
|
|
97
|
+
result.error ?? "The AI session exchange failed."
|
|
98
|
+
);
|
|
99
|
+
}
|
|
100
|
+
const connection = {
|
|
101
|
+
baseUrl: result.agent.base_url,
|
|
102
|
+
agentId: result.agent.agent_id
|
|
103
|
+
};
|
|
104
|
+
setQwenpawSessionCookies(event, connection);
|
|
105
|
+
return connection;
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
export { QwenpawExchangeError as Q, resolveQwenpawConnection as a, resolveQwenpawServerConfig as b, exchangeQwenpawSession as e, hasQwenpawConnection as h, requireCmsSession as r };
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
const QWENPAW_COOKIE_BASE_URL = "qwenpaw_base_url";
|
|
2
|
+
const QWENPAW_COOKIE_AGENT_ID = "qwenpaw_agent_id";
|
|
3
|
+
const QWENPAW_COOKIE_MAX_AGE = 600;
|
|
4
|
+
const QWENPAW_RUNTIME_CONFIG_KEY = "qwenpaw";
|
|
5
|
+
const QWENPAW_DEFAULT_AGENT_ID = "default";
|
|
6
|
+
const QWENPAW_CHANNEL = "console";
|
|
7
|
+
const QWENPAW_MAX_MESSAGE_LENGTH = 32e3;
|
|
8
|
+
const QWENPAW_MAX_SESSION_ID_LENGTH = 200;
|
|
9
|
+
const QWENPAW_MAX_FILES = 5;
|
|
10
|
+
const QWENPAW_MAX_FILE_NAME_LENGTH = 255;
|
|
11
|
+
const QWENPAW_MAX_UPLOAD_BYTES = 20 * 1024 * 1024;
|
|
12
|
+
const QWENPAW_CHAT_TIMEOUT_MS = 3e4;
|
|
13
|
+
const QWENPAW_STOP_TIMEOUT_MS = 1e4;
|
|
14
|
+
const QWENPAW_UPLOAD_TIMEOUT_MS = 3e4;
|
|
15
|
+
const QWENPAW_EXCHANGE_TIMEOUT_MS = 3e4;
|
|
16
|
+
const QWENPAW_LIST_TIMEOUT_MS = 15e3;
|
|
17
|
+
const QWENPAW_MAX_HISTORY_TURNS = 200;
|
|
18
|
+
const QWENPAW_EXCHANGE_ACTION_PATH = "/api/v1/content/types/gov.agent/actions/exchange_ai_credential";
|
|
19
|
+
const QWENPAW_CONFIGURATION_ERROR_CODES = /* @__PURE__ */ new Set([
|
|
20
|
+
"AI_AGENT_NOT_ASSIGNED",
|
|
21
|
+
"AI_CREDENTIAL_NOT_CONFIGURED"
|
|
22
|
+
]);
|
|
23
|
+
|
|
24
|
+
export { QWENPAW_MAX_MESSAGE_LENGTH as Q, QWENPAW_MAX_FILES as a, QWENPAW_MAX_FILE_NAME_LENGTH as b, QWENPAW_MAX_SESSION_ID_LENGTH as c, QWENPAW_LIST_TIMEOUT_MS as d, QWENPAW_DEFAULT_AGENT_ID as e, QWENPAW_MAX_HISTORY_TURNS as f, QWENPAW_MAX_UPLOAD_BYTES as g, QWENPAW_CHANNEL as h, QWENPAW_CHAT_TIMEOUT_MS as i, QWENPAW_STOP_TIMEOUT_MS as j, QWENPAW_UPLOAD_TIMEOUT_MS as k, QWENPAW_COOKIE_AGENT_ID as l, QWENPAW_COOKIE_BASE_URL as m, QWENPAW_RUNTIME_CONFIG_KEY as n, QWENPAW_EXCHANGE_ACTION_PATH as o, QWENPAW_EXCHANGE_TIMEOUT_MS as p, QWENPAW_CONFIGURATION_ERROR_CODES as q, QWENPAW_COOKIE_MAX_AGE as r };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/common/constants/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC;AAChC,cAAc,oBAAoB,CAAC;AACnC,cAAc,oBAAoB,CAAC;AACnC,cAAc,0BAA0B,CAAC;AACzC,cAAc,0BAA0B,CAAC;AACzC,cAAc,uBAAuB,CAAC;AACtC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,uBAAuB,CAAC;AACtC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,kBAAkB,CAAC;AACjC,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC;AACnC,cAAc,mBAAmB,CAAC;AAClC,cAAc,iBAAiB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/common/constants/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC;AAChC,cAAc,oBAAoB,CAAC;AACnC,cAAc,oBAAoB,CAAC;AACnC,cAAc,0BAA0B,CAAC;AACzC,cAAc,0BAA0B,CAAC;AACzC,cAAc,uBAAuB,CAAC;AACtC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,uBAAuB,CAAC;AACtC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,kBAAkB,CAAC;AACjC,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC;AACnC,cAAc,mBAAmB,CAAC;AAClC,cAAc,iBAAiB,CAAC;AAChC,cAAc,oBAAoB,CAAC"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* QwenPaw AI chat — shared constants (server routes + client store).
|
|
3
|
+
*
|
|
4
|
+
* The browser never supplies agent credentials: the server invokes the
|
|
5
|
+
* `exchange_ai_credential` pack action with the user's CMS session and
|
|
6
|
+
* stashes the verified connection in temporary httpOnly cookies.
|
|
7
|
+
* Agents are reached POD-TO-POD (`http://<name>.<ns>.svc:8088`) with
|
|
8
|
+
* web-auth DISABLED — no Authorization header is sent upstream.
|
|
9
|
+
*/
|
|
10
|
+
/** httpOnly cookies carrying the exchanged session (TTL-bound). */
|
|
11
|
+
export declare const QWENPAW_COOKIE_BASE_URL = "qwenpaw_base_url";
|
|
12
|
+
export declare const QWENPAW_COOKIE_AGENT_ID = "qwenpaw_agent_id";
|
|
13
|
+
/** All connection cookies — cleared together on session reset. */
|
|
14
|
+
export declare const QWENPAW_SESSION_COOKIES: readonly ["qwenpaw_base_url", "qwenpaw_agent_id"];
|
|
15
|
+
/** Mirror of the exchange action's SESSION_TTL_SECONDS (600s). */
|
|
16
|
+
export declare const QWENPAW_COOKIE_MAX_AGE = 600;
|
|
17
|
+
/** Server-side runtimeConfig namespace: `runtimeConfig.qwenpaw.*`. */
|
|
18
|
+
export declare const QWENPAW_RUNTIME_CONFIG_KEY = "qwenpaw";
|
|
19
|
+
/** Default agent id when neither the exchange nor env provides one. */
|
|
20
|
+
export declare const QWENPAW_DEFAULT_AGENT_ID = "default";
|
|
21
|
+
/** Agent id validation — safe for URLs and QwenPaw headers. */
|
|
22
|
+
export declare const QWENPAW_AGENT_ID_PATTERN: RegExp;
|
|
23
|
+
/** Channel used for application-driven chats. */
|
|
24
|
+
export declare const QWENPAW_CHANNEL = "console";
|
|
25
|
+
/** Request limits enforced by the chat route. */
|
|
26
|
+
export declare const QWENPAW_MAX_MESSAGE_LENGTH = 32000;
|
|
27
|
+
export declare const QWENPAW_MAX_SESSION_ID_LENGTH = 200;
|
|
28
|
+
export declare const QWENPAW_MAX_FILES = 5;
|
|
29
|
+
export declare const QWENPAW_MAX_FILE_NAME_LENGTH = 255;
|
|
30
|
+
/** Upload ceiling — matches a generous document size. */
|
|
31
|
+
export declare const QWENPAW_MAX_UPLOAD_BYTES: number;
|
|
32
|
+
/** Wall-clock budgets (ms) for upstream establishment. */
|
|
33
|
+
export declare const QWENPAW_CHAT_TIMEOUT_MS = 30000;
|
|
34
|
+
export declare const QWENPAW_STOP_TIMEOUT_MS = 10000;
|
|
35
|
+
export declare const QWENPAW_UPLOAD_TIMEOUT_MS = 30000;
|
|
36
|
+
export declare const QWENPAW_EXCHANGE_TIMEOUT_MS = 30000;
|
|
37
|
+
export declare const QWENPAW_LIST_TIMEOUT_MS = 15000;
|
|
38
|
+
/** QwenPaw conversation history cap — the most recent context matters. */
|
|
39
|
+
export declare const QWENPAW_MAX_HISTORY_TURNS = 200;
|
|
40
|
+
/** Pack action that exchanges the user's CMS session for an AI session. */
|
|
41
|
+
export declare const QWENPAW_EXCHANGE_ACTION_PATH = "/api/v1/content/types/gov.agent/actions/exchange_ai_credential";
|
|
42
|
+
/** Codes the UI renders as "ask an admin" (403) vs "retry" (423). */
|
|
43
|
+
export declare const QWENPAW_CONFIGURATION_ERROR_CODES: ReadonlySet<string>;
|
|
44
|
+
/** Nuxt-module server routes (registered via addServerHandler). */
|
|
45
|
+
export declare const QWENPAW_API_BASE = "/api/cms/ai/qwenpaw";
|
|
46
|
+
//# sourceMappingURL=qwenpaw.constant.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"qwenpaw.constant.d.ts","sourceRoot":"","sources":["../../../src/common/constants/qwenpaw.constant.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,mEAAmE;AACnE,eAAO,MAAM,uBAAuB,qBAAqB,CAAC;AAC1D,eAAO,MAAM,uBAAuB,qBAAqB,CAAC;AAE1D,kEAAkE;AAClE,eAAO,MAAM,uBAAuB,mDAA8D,CAAC;AAEnG,kEAAkE;AAClE,eAAO,MAAM,sBAAsB,MAAM,CAAC;AAE1C,sEAAsE;AACtE,eAAO,MAAM,0BAA0B,YAAY,CAAC;AAEpD,uEAAuE;AACvE,eAAO,MAAM,wBAAwB,YAAY,CAAC;AAElD,+DAA+D;AAC/D,eAAO,MAAM,wBAAwB,QAA4B,CAAC;AAElE,iDAAiD;AACjD,eAAO,MAAM,eAAe,YAAY,CAAC;AAEzC,iDAAiD;AACjD,eAAO,MAAM,0BAA0B,QAAS,CAAC;AACjD,eAAO,MAAM,6BAA6B,MAAM,CAAC;AACjD,eAAO,MAAM,iBAAiB,IAAI,CAAC;AACnC,eAAO,MAAM,4BAA4B,MAAM,CAAC;AAEhD,yDAAyD;AACzD,eAAO,MAAM,wBAAwB,QAAmB,CAAC;AAEzD,0DAA0D;AAC1D,eAAO,MAAM,uBAAuB,QAAS,CAAC;AAC9C,eAAO,MAAM,uBAAuB,QAAS,CAAC;AAC9C,eAAO,MAAM,yBAAyB,QAAS,CAAC;AAChD,eAAO,MAAM,2BAA2B,QAAS,CAAC;AAClD,eAAO,MAAM,uBAAuB,QAAS,CAAC;AAE9C,0EAA0E;AAC1E,eAAO,MAAM,yBAAyB,MAAM,CAAC;AAE7C,2EAA2E;AAC3E,eAAO,MAAM,4BAA4B,mEACyB,CAAC;AAEnE,qEAAqE;AACrE,eAAO,MAAM,iCAAiC,EAAE,WAAW,CAAC,MAAM,CAGhE,CAAC;AAEH,mEAAmE;AACnE,eAAO,MAAM,gBAAgB,wBAAwB,CAAC"}
|