@meistrari/chat-nuxt 1.4.0 → 1.5.0
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/README.md +51 -16
- package/dist/module.json +1 -1
- package/dist/module.mjs +12 -8
- package/dist/runtime/components/MeistrariChatEmbed.d.vue.ts +2 -18
- package/dist/runtime/components/MeistrariChatEmbed.vue +22 -4
- package/dist/runtime/components/MeistrariChatEmbed.vue.d.ts +2 -18
- package/dist/runtime/components/chat/message-input.d.vue.ts +30 -4
- package/dist/runtime/components/chat/message-input.vue +268 -24
- package/dist/runtime/components/chat/message-input.vue.d.ts +30 -4
- package/dist/runtime/composables/useChat.d.ts +3 -5
- package/dist/runtime/composables/useChat.js +18 -4
- package/dist/runtime/composables/useChatApi.js +4 -0
- package/dist/runtime/composables/useConversations.js +8 -2
- package/dist/runtime/composables/useEmbedConfig.d.ts +7 -1
- package/dist/runtime/composables/useEmbedConfig.js +8 -0
- package/dist/runtime/composables/useFeatureFlags.d.ts +1 -2
- package/dist/runtime/composables/useTelaAgentMetadata.d.ts +8 -0
- package/dist/runtime/composables/useTelaAgentMetadata.js +65 -0
- package/dist/runtime/composables/useWorkspaceSettings.d.ts +1 -19
- package/dist/runtime/embed/components/ChatConfigurationModal.d.vue.ts +1 -1
- package/dist/runtime/embed/components/ChatConfigurationModal.vue.d.ts +1 -1
- package/dist/runtime/embed/components/ChatEmbed.d.vue.ts +3 -23
- package/dist/runtime/embed/components/ChatEmbed.vue +34 -9
- package/dist/runtime/embed/components/ChatEmbed.vue.d.ts +3 -23
- package/dist/runtime/embed/components/ChatEmbedInner.vue +36 -12
- package/dist/runtime/plugins/markstream.d.ts +1 -1
- package/dist/runtime/plugins/markstream.js +1 -1
- package/dist/runtime/server/api/conversations/[id]/cancel.post.d.ts +1 -1
- package/dist/runtime/server/api/conversations/[id]/cancel.post.js +37 -17
- package/dist/runtime/server/api/conversations/[id]/clear.post.js +28 -13
- package/dist/runtime/server/api/conversations/[id]/duplicate.post.js +11 -13
- package/dist/runtime/server/api/conversations/[id]/files.get.js +5 -7
- package/dist/runtime/server/api/conversations/[id]/index.delete.js +13 -12
- package/dist/runtime/server/api/conversations/[id]/index.get.js +6 -13
- package/dist/runtime/server/api/conversations/[id]/index.patch.js +11 -10
- package/dist/runtime/server/api/conversations/[id]/messages/[messageId]/retry.post.js +46 -80
- package/dist/runtime/server/api/conversations/[id]/messages/index.get.d.ts +1 -14
- package/dist/runtime/server/api/conversations/[id]/messages/index.get.js +81 -187
- package/dist/runtime/server/api/conversations/[id]/messages/index.post.js +68 -86
- package/dist/runtime/server/api/conversations/[id]/usage.get.js +4 -8
- package/dist/runtime/server/api/conversations/generate-title.post.js +4 -3
- package/dist/runtime/server/api/conversations/index.get.js +5 -4
- package/dist/runtime/server/api/conversations/index.post.js +5 -4
- package/dist/runtime/server/api/tela/agents/[id].get.d.ts +6 -0
- package/dist/runtime/server/api/tela/agents/[id].get.js +25 -0
- package/dist/runtime/server/api/workspace/settings.patch.js +1 -1
- package/dist/runtime/server/db/schema/conversations.d.ts +17 -0
- package/dist/runtime/server/db/schema/conversations.js +3 -1
- package/dist/runtime/server/db/schema/workspace-settings.d.ts +1 -1
- package/dist/runtime/server/utils/chat-context.d.ts +5 -0
- package/dist/runtime/server/utils/chat-context.js +20 -0
- package/dist/runtime/server/utils/conversation-agent-turn.d.ts +39 -0
- package/dist/runtime/server/utils/conversation-agent-turn.js +170 -0
- package/dist/runtime/server/utils/conversation-message-files.d.ts +10 -0
- package/dist/runtime/server/utils/conversation-message-files.js +77 -0
- package/dist/runtime/server/utils/conversation-message-sync.d.ts +31 -0
- package/dist/runtime/server/utils/conversation-message-sync.js +132 -0
- package/dist/runtime/server/utils/conversation-scope.d.ts +2 -0
- package/dist/runtime/server/utils/conversation-scope.js +12 -0
- package/dist/runtime/server/utils/tela-agent-api.d.ts +29 -0
- package/dist/runtime/server/utils/tela-agent-api.js +107 -0
- package/dist/runtime/server/utils/tela-agent-session.d.ts +48 -0
- package/dist/runtime/server/utils/tela-agent-session.js +350 -0
- package/dist/runtime/types/embed.d.ts +29 -0
- package/dist/runtime/types/embed.js +0 -0
- package/dist/runtime/types/tela-agent.d.ts +243 -0
- package/dist/runtime/types/tela-agent.js +98 -0
- package/dist/runtime/types/workspace-settings-data.d.ts +19 -0
- package/dist/runtime/types/workspace-settings-data.js +0 -0
- package/dist/runtime/types/workspace-settings.d.ts +1 -1
- package/dist/runtime/utils/agent-input-readiness.d.ts +14 -0
- package/dist/runtime/utils/agent-input-readiness.js +15 -0
- package/dist/runtime/utils/features.d.ts +9 -0
- package/dist/runtime/utils/features.js +5 -4
- package/dist/runtime/utils/file.js +46 -7
- package/dist/runtime/utils/markdown-nodes.d.ts +1 -0
- package/dist/runtime/utils/markdown-nodes.js +6 -0
- package/dist/runtime/utils/tela-chat.d.ts +6 -0
- package/dist/runtime/utils/tela-chat.js +12 -1
- package/drizzle/0014_faulty_lake.sql +2 -0
- package/drizzle/meta/0014_snapshot.json +732 -0
- package/drizzle/meta/_journal.json +7 -0
- package/package.json +1 -1
- package/dist/runtime/types/feature-flags.d.ts +0 -7
- package/dist/runtime/types/feature-flags.js +0 -6
|
@@ -1,25 +1,21 @@
|
|
|
1
1
|
import { createError, defineEventHandler, getRouterParam, readBody } from "h3";
|
|
2
|
-
import {
|
|
3
|
-
import { eq, and, isNull } from "drizzle-orm";
|
|
2
|
+
import { eq } from "drizzle-orm";
|
|
4
3
|
import { useDb, schema } from "#chat-runtime/server/db";
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
4
|
+
import { resolveChatRuntimeContext } from "#chat-runtime/server/utils/chat-context";
|
|
5
|
+
import {
|
|
6
|
+
buildTelaAgentTurnPayload,
|
|
7
|
+
prepareDefaultAgentTurn,
|
|
8
|
+
queueTelaAgentTurn,
|
|
9
|
+
resolveDefaultAgentEnvironmentVariables,
|
|
10
|
+
withEnvironmentVariables
|
|
11
|
+
} from "#chat-runtime/server/utils/conversation-agent-turn";
|
|
12
|
+
import { conversationScopeConditions } from "#chat-runtime/server/utils/conversation-scope";
|
|
7
13
|
import { getAgentDataToken, createChatAgentSession, continueSession } from "#chat-runtime/server/utils/agent-api";
|
|
8
14
|
import { logger } from "#chat-runtime/server/utils/logger";
|
|
9
|
-
import {
|
|
10
|
-
getConversationAppliedSettings,
|
|
11
|
-
getWorkspaceSettingsUpdatedAt,
|
|
12
|
-
parseWorkspaceSettingsSnapshot,
|
|
13
|
-
resolveWorkspaceSettings,
|
|
14
|
-
serializeResolvedWorkspaceSettings
|
|
15
|
-
} from "#chat-runtime/server/utils/chat-workspace-settings";
|
|
16
|
-
import { resolveWorkspaceCredentials } from "#chat-runtime/server/utils/workspace";
|
|
17
|
-
import { useChatNuxtFeatures } from "#chat-runtime/utils/features";
|
|
18
|
-
import { mergeFileUrls } from "#chat-runtime/utils/file";
|
|
19
15
|
import { isValidModel } from "#chat-runtime/types/chat";
|
|
16
|
+
import { telaAgentExecutionInputSchema } from "#chat-runtime/types/tela-agent";
|
|
20
17
|
export default defineEventHandler(async (event) => {
|
|
21
|
-
const context =
|
|
22
|
-
const token = getAgentDataToken(event);
|
|
18
|
+
const context = resolveChatRuntimeContext(event);
|
|
23
19
|
const db = useDb();
|
|
24
20
|
const conversationId = getRouterParam(event, "id");
|
|
25
21
|
const body = await readBody(event);
|
|
@@ -35,41 +31,37 @@ export default defineEventHandler(async (event) => {
|
|
|
35
31
|
statusMessage: "Message content is required"
|
|
36
32
|
});
|
|
37
33
|
}
|
|
38
|
-
|
|
34
|
+
const [conversation] = await db.select().from(schema.conversations).where(conversationScopeConditions(context, conversationId));
|
|
35
|
+
if (!conversation) {
|
|
36
|
+
throw createError({
|
|
37
|
+
statusCode: 404,
|
|
38
|
+
statusMessage: "Conversation not found"
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
if (!conversation.telaAgentId && body.model !== void 0 && !isValidModel(body.model)) {
|
|
39
42
|
throw createError({
|
|
40
43
|
statusCode: 400,
|
|
41
44
|
statusMessage: "Invalid model"
|
|
42
45
|
});
|
|
43
46
|
}
|
|
44
|
-
const
|
|
45
|
-
|
|
46
|
-
eq(schema.conversations.id, conversationId),
|
|
47
|
-
eq(schema.conversations.workspaceId, context.workspaceId)
|
|
48
|
-
)
|
|
49
|
-
);
|
|
50
|
-
if (!conversation) {
|
|
47
|
+
const agentInputs = conversation.telaAgentId && body.agentInputs !== void 0 ? telaAgentExecutionInputSchema.array().safeParse(body.agentInputs) : null;
|
|
48
|
+
if (agentInputs && !agentInputs.success) {
|
|
51
49
|
throw createError({
|
|
52
|
-
statusCode:
|
|
53
|
-
statusMessage: "
|
|
50
|
+
statusCode: 400,
|
|
51
|
+
statusMessage: "Invalid Tela agent inputs"
|
|
54
52
|
});
|
|
55
53
|
}
|
|
56
|
-
const
|
|
57
|
-
const
|
|
58
|
-
|
|
59
|
-
|
|
54
|
+
const telaAgentPayload = conversation.telaAgentId ? await buildTelaAgentTurnPayload(event, conversation, body.content, body.files, agentInputs?.data) : null;
|
|
55
|
+
const defaultAgentTurn = conversation.telaAgentId ? null : await prepareDefaultAgentTurn(event, db, context, {
|
|
56
|
+
conversation,
|
|
57
|
+
conversationId,
|
|
58
|
+
content: body.content,
|
|
59
|
+
files: body.files,
|
|
60
|
+
requestedModel: body.model,
|
|
61
|
+
workspaceSettingsSnapshot: body.workspaceSettingsSnapshot
|
|
62
|
+
});
|
|
60
63
|
const now = /* @__PURE__ */ new Date();
|
|
61
64
|
const assistantCreatedAt = new Date(now.getTime() + 1);
|
|
62
|
-
const snapshotSettings = explicitSettings ?? trustedSettings;
|
|
63
|
-
if (!conversation.appliedSettingsSnapshot && snapshotSettings) {
|
|
64
|
-
await db.update(schema.conversations).set({
|
|
65
|
-
appliedSettingsAt: getWorkspaceSettingsUpdatedAt(snapshotSettings),
|
|
66
|
-
appliedSettingsSnapshot: serializeResolvedWorkspaceSettings(snapshotSettings),
|
|
67
|
-
updatedAt: now
|
|
68
|
-
}).where(and(
|
|
69
|
-
eq(schema.conversations.id, conversationId),
|
|
70
|
-
isNull(schema.conversations.appliedSettingsSnapshot)
|
|
71
|
-
));
|
|
72
|
-
}
|
|
73
65
|
const [userMessages, assistantMessages] = await Promise.all([
|
|
74
66
|
db.insert(schema.messages).values({
|
|
75
67
|
conversationId,
|
|
@@ -98,49 +90,42 @@ export default defineEventHandler(async (event) => {
|
|
|
98
90
|
}
|
|
99
91
|
logger.info({ conversationId, userMessageId: userMessage.id, hasFiles: !!body.files?.length }, "Message sent");
|
|
100
92
|
const assistantMessageId = assistantMessage.id;
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
fileUrls,
|
|
131
|
-
model: effectiveModel,
|
|
132
|
-
customTools: canvasTools?.length ? { canvas: canvasTools } : void 0,
|
|
133
|
-
tools: hasKnowledgeSources ? { workstationQueryTool: true } : void 0,
|
|
134
|
-
environmentVariables: hasEnvironmentVariables ? environmentVariables : void 0,
|
|
135
|
-
skills
|
|
136
|
-
}).then(async (result) => {
|
|
93
|
+
if (conversation.telaAgentId) {
|
|
94
|
+
queueTelaAgentTurn(event, db, {
|
|
95
|
+
conversation,
|
|
96
|
+
conversationId,
|
|
97
|
+
assistantMessageId,
|
|
98
|
+
payload: telaAgentPayload,
|
|
99
|
+
titleContent: body.content,
|
|
100
|
+
operation: "send"
|
|
101
|
+
});
|
|
102
|
+
return {
|
|
103
|
+
userMessage,
|
|
104
|
+
assistantMessage
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
if (!defaultAgentTurn) {
|
|
108
|
+
throw createError({
|
|
109
|
+
statusCode: 500,
|
|
110
|
+
statusMessage: "Failed to prepare agent turn"
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
const token = getAgentDataToken(event);
|
|
114
|
+
if (defaultAgentTurn.needsNewThread) {
|
|
115
|
+
const environmentVariables = await resolveDefaultAgentEnvironmentVariables(
|
|
116
|
+
event,
|
|
117
|
+
context,
|
|
118
|
+
{ conversationId },
|
|
119
|
+
"Failed to resolve workspace credentials, proceeding without env vars"
|
|
120
|
+
);
|
|
121
|
+
createChatAgentSession(token, withEnvironmentVariables(defaultAgentTurn.createPayload, environmentVariables)).then(async (result) => {
|
|
137
122
|
if (result.success) {
|
|
138
123
|
logger.info({ conversationId, sessionId: result.sessionId }, "New agent thread created");
|
|
139
124
|
await db.update(schema.conversations).set({
|
|
140
125
|
threadSessionId: result.sessionId,
|
|
141
|
-
title: messageTitle,
|
|
142
|
-
appliedSettingsAt: settingsTimestamp,
|
|
143
|
-
model: effectiveModel ?? null,
|
|
126
|
+
title: defaultAgentTurn.messageTitle,
|
|
127
|
+
appliedSettingsAt: defaultAgentTurn.settingsTimestamp,
|
|
128
|
+
model: defaultAgentTurn.effectiveModel ?? null,
|
|
144
129
|
updatedAt: /* @__PURE__ */ new Date()
|
|
145
130
|
}).where(eq(schema.conversations.id, conversationId));
|
|
146
131
|
} else {
|
|
@@ -158,20 +143,17 @@ export default defineEventHandler(async (event) => {
|
|
|
158
143
|
}).where(eq(schema.messages.id, assistantMessageId));
|
|
159
144
|
});
|
|
160
145
|
} else {
|
|
161
|
-
continueSession(token, conversation.threadSessionId, {
|
|
162
|
-
content: body.content.trim(),
|
|
163
|
-
fileUrls,
|
|
164
|
-
model: effectiveModel
|
|
165
|
-
}).then(async (result) => {
|
|
146
|
+
continueSession(token, conversation.threadSessionId, defaultAgentTurn.continuePayload).then(async (result) => {
|
|
166
147
|
if (!result.success) {
|
|
167
148
|
logger.warn({ conversationId, sessionId: conversation.threadSessionId, error: result.error }, "Agent session continue failed");
|
|
168
149
|
await db.update(schema.messages).set({
|
|
169
150
|
content: `Erro: ${result.error}`,
|
|
170
151
|
status: "failed"
|
|
171
152
|
}).where(eq(schema.messages.id, assistantMessageId));
|
|
153
|
+
return;
|
|
172
154
|
}
|
|
173
155
|
await db.update(schema.conversations).set({
|
|
174
|
-
...effectiveModel ? { model: effectiveModel } : {},
|
|
156
|
+
...defaultAgentTurn.effectiveModel ? { model: defaultAgentTurn.effectiveModel } : {},
|
|
175
157
|
updatedAt: /* @__PURE__ */ new Date()
|
|
176
158
|
}).where(eq(schema.conversations.id, conversationId));
|
|
177
159
|
}).catch(async (e) => {
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { createError, defineEventHandler, getRouterParam } from "h3";
|
|
2
2
|
import { eq, and } from "drizzle-orm";
|
|
3
3
|
import { useDb, schema } from "#chat-runtime/server/db";
|
|
4
|
-
import {
|
|
4
|
+
import { resolveChatRuntimeContext } from "#chat-runtime/server/utils/chat-context";
|
|
5
|
+
import { conversationScopeConditions } from "#chat-runtime/server/utils/conversation-scope";
|
|
5
6
|
import { getWorkspaceBilling, transformCostForBilling } from "#chat-runtime/server/utils/billing";
|
|
6
7
|
export default defineEventHandler(async (event) => {
|
|
7
|
-
const context =
|
|
8
|
+
const context = resolveChatRuntimeContext(event);
|
|
8
9
|
const db = useDb();
|
|
9
10
|
const id = getRouterParam(event, "id");
|
|
10
11
|
if (!id) {
|
|
@@ -13,12 +14,7 @@ export default defineEventHandler(async (event) => {
|
|
|
13
14
|
statusMessage: "Conversation ID is required"
|
|
14
15
|
});
|
|
15
16
|
}
|
|
16
|
-
const [conversation] = await db.select({ id: schema.conversations.id }).from(schema.conversations).where(
|
|
17
|
-
and(
|
|
18
|
-
eq(schema.conversations.id, id),
|
|
19
|
-
eq(schema.conversations.workspaceId, context.workspaceId)
|
|
20
|
-
)
|
|
21
|
-
);
|
|
17
|
+
const [conversation] = await db.select({ id: schema.conversations.id }).from(schema.conversations).where(conversationScopeConditions(context, id));
|
|
22
18
|
if (!conversation) {
|
|
23
19
|
throw createError({
|
|
24
20
|
statusCode: 404,
|
|
@@ -3,7 +3,7 @@ import { useRuntimeConfig } from "nitropack/runtime";
|
|
|
3
3
|
import { createTelaClient } from "@meistrari/tela-sdk-js";
|
|
4
4
|
import { logger } from "#chat-runtime/server/utils/logger";
|
|
5
5
|
import { requireUser } from "#chat-runtime/server/utils/auth";
|
|
6
|
-
import {
|
|
6
|
+
import { resolveChatNuxtFeatures } from "#chat-runtime/utils/features";
|
|
7
7
|
const TITLE_CANVAS_ID = "ba06c4a0-ef05-4fb6-b4ef-5af3d63a1ba2";
|
|
8
8
|
const FALLBACK_TITLE_MAX_LENGTH = 60;
|
|
9
9
|
const FALLBACK_TITLE_DEFAULT = "New chat";
|
|
@@ -26,8 +26,9 @@ export default defineEventHandler(async (event) => {
|
|
|
26
26
|
statusMessage: "userMessage and assistantResponse are required"
|
|
27
27
|
});
|
|
28
28
|
}
|
|
29
|
-
const
|
|
30
|
-
const
|
|
29
|
+
const runtimeConfig = useRuntimeConfig();
|
|
30
|
+
const { telaApiKey } = runtimeConfig;
|
|
31
|
+
const features = resolveChatNuxtFeatures(runtimeConfig);
|
|
31
32
|
if (!features.generateTitle || !telaApiKey) {
|
|
32
33
|
const fallback = buildFallbackTitle(userMessage);
|
|
33
34
|
logger.debug({ titleLength: fallback.length, reason: !features.generateTitle ? "feature-disabled" : "no-tela-api-key" }, "Title generated via fallback");
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import { defineEventHandler } from "h3";
|
|
2
|
-
import { desc
|
|
2
|
+
import { desc } from "drizzle-orm";
|
|
3
3
|
import { useDb, schema } from "#chat-runtime/server/db";
|
|
4
|
-
import {
|
|
4
|
+
import { resolveChatRuntimeContext } from "#chat-runtime/server/utils/chat-context";
|
|
5
|
+
import { conversationScopeConditions } from "#chat-runtime/server/utils/conversation-scope";
|
|
5
6
|
import { logger } from "#chat-runtime/server/utils/logger";
|
|
6
7
|
export default defineEventHandler(async (event) => {
|
|
7
|
-
const context =
|
|
8
|
+
const context = resolveChatRuntimeContext(event);
|
|
8
9
|
const db = useDb();
|
|
9
|
-
const conversations = await db.select().from(schema.conversations).where(
|
|
10
|
+
const conversations = await db.select().from(schema.conversations).where(conversationScopeConditions(context)).orderBy(desc(schema.conversations.updatedAt));
|
|
10
11
|
logger.debug({ workspaceId: context.workspaceId, count: conversations.length }, "Conversations listed");
|
|
11
12
|
return conversations;
|
|
12
13
|
});
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { createError, defineEventHandler, getRequestHeader, readBody } from "h3";
|
|
2
2
|
import { useDb, schema } from "#chat-runtime/server/db";
|
|
3
|
-
import {
|
|
3
|
+
import { resolveChatRuntimeContext } from "#chat-runtime/server/utils/chat-context";
|
|
4
4
|
import { logger } from "#chat-runtime/server/utils/logger";
|
|
5
5
|
import { isValidModel } from "#chat-runtime/types/chat";
|
|
6
6
|
export default defineEventHandler(async (event) => {
|
|
7
|
-
const context =
|
|
7
|
+
const context = resolveChatRuntimeContext(event);
|
|
8
8
|
const db = useDb();
|
|
9
9
|
let body = {};
|
|
10
10
|
const contentLength = getRequestHeader(event, "content-length");
|
|
@@ -19,7 +19,7 @@ export default defineEventHandler(async (event) => {
|
|
|
19
19
|
});
|
|
20
20
|
}
|
|
21
21
|
}
|
|
22
|
-
if (body.model !== void 0 && body.model !== null && !isValidModel(body.model)) {
|
|
22
|
+
if (!context.telaAgentId && body.model !== void 0 && body.model !== null && !isValidModel(body.model)) {
|
|
23
23
|
throw createError({
|
|
24
24
|
statusCode: 400,
|
|
25
25
|
statusMessage: "Invalid model"
|
|
@@ -29,7 +29,8 @@ export default defineEventHandler(async (event) => {
|
|
|
29
29
|
workspaceId: context.workspaceId,
|
|
30
30
|
userId: context.user.id,
|
|
31
31
|
createdBy: context.user.email,
|
|
32
|
-
|
|
32
|
+
telaAgentId: context.telaAgentId,
|
|
33
|
+
...context.telaAgentId ? { model: null } : body.model ? { model: body.model } : {}
|
|
33
34
|
}).returning();
|
|
34
35
|
if (!conversation) {
|
|
35
36
|
throw createError({
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { createError, defineEventHandler, getRouterParam } from "h3";
|
|
2
|
+
import { requireUser } from "#chat-runtime/server/utils/auth";
|
|
3
|
+
import { getTelaAgent } from "#chat-runtime/server/utils/tela-agent-api";
|
|
4
|
+
export default defineEventHandler(async (event) => {
|
|
5
|
+
requireUser(event);
|
|
6
|
+
const agentId = getRouterParam(event, "id")?.trim();
|
|
7
|
+
if (!agentId) {
|
|
8
|
+
throw createError({
|
|
9
|
+
statusCode: 400,
|
|
10
|
+
statusMessage: "Agent ID is required"
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
const result = await getTelaAgent(event, agentId);
|
|
14
|
+
if (!result.success) {
|
|
15
|
+
throw createError({
|
|
16
|
+
statusCode: 502,
|
|
17
|
+
statusMessage: result.error
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
return {
|
|
21
|
+
id: result.data.id,
|
|
22
|
+
inputSchema: result.data.inputSchema,
|
|
23
|
+
isMultiturn: result.data.isMultiturn ?? null
|
|
24
|
+
};
|
|
25
|
+
});
|
|
@@ -55,7 +55,7 @@ export default defineEventHandler(async (event) => {
|
|
|
55
55
|
name: skill.name,
|
|
56
56
|
description: skill.description,
|
|
57
57
|
runtime: skill.runtime,
|
|
58
|
-
allowedTools: skill.allowedTools,
|
|
58
|
+
allowedTools: [...skill.allowedTools],
|
|
59
59
|
isPublic: skill.isPublic,
|
|
60
60
|
addedByUserId: skill.addedBy?.userId || session.user.id,
|
|
61
61
|
addedByUsername: skill.addedBy?.username || session.user.name || "",
|
|
@@ -88,6 +88,23 @@ export declare const conversations: import("drizzle-orm/pg-core").PgTableWithCol
|
|
|
88
88
|
identity: undefined;
|
|
89
89
|
generated: undefined;
|
|
90
90
|
}, {}, {}>;
|
|
91
|
+
telaAgentId: import("drizzle-orm/pg-core").PgColumn<{
|
|
92
|
+
name: "tela_agent_id";
|
|
93
|
+
tableName: "conversations";
|
|
94
|
+
dataType: "string";
|
|
95
|
+
columnType: "PgText";
|
|
96
|
+
data: string;
|
|
97
|
+
driverParam: string;
|
|
98
|
+
notNull: false;
|
|
99
|
+
hasDefault: false;
|
|
100
|
+
isPrimaryKey: false;
|
|
101
|
+
isAutoincrement: false;
|
|
102
|
+
hasRuntimeDefault: false;
|
|
103
|
+
enumValues: [string, ...string[]];
|
|
104
|
+
baseColumn: never;
|
|
105
|
+
identity: undefined;
|
|
106
|
+
generated: undefined;
|
|
107
|
+
}, {}, {}>;
|
|
91
108
|
model: import("drizzle-orm/pg-core").PgColumn<{
|
|
92
109
|
name: "model";
|
|
93
110
|
tableName: "conversations";
|
|
@@ -6,6 +6,7 @@ export const conversations = chatSchema.table("conversations", {
|
|
|
6
6
|
userId: text("user_id").notNull(),
|
|
7
7
|
title: text("title").notNull().default("Nova conversa"),
|
|
8
8
|
threadSessionId: text("thread_session_id"),
|
|
9
|
+
telaAgentId: text("tela_agent_id"),
|
|
9
10
|
model: text("model").default("claude-sonnet-4-5"),
|
|
10
11
|
appliedSettingsAt: timestamp("applied_settings_at", { withTimezone: true }),
|
|
11
12
|
appliedSettingsSnapshot: jsonb("applied_settings_snapshot").$type(),
|
|
@@ -15,5 +16,6 @@ export const conversations = chatSchema.table("conversations", {
|
|
|
15
16
|
}, (table) => [
|
|
16
17
|
index("idx_conversations_workspace").on(table.workspaceId),
|
|
17
18
|
index("idx_conversations_user").on(table.userId),
|
|
18
|
-
index("idx_conversations_updated").on(table.updatedAt)
|
|
19
|
+
index("idx_conversations_updated").on(table.updatedAt),
|
|
20
|
+
index("idx_conversations_workspace_tela_agent_updated").on(table.workspaceId, table.telaAgentId, table.updatedAt)
|
|
19
21
|
]);
|
|
@@ -4,6 +4,11 @@ export type ChatContext = {
|
|
|
4
4
|
user: AppSession['user'];
|
|
5
5
|
workspaceId: string;
|
|
6
6
|
};
|
|
7
|
+
export type ChatRuntimeContext = ChatContext & {
|
|
8
|
+
telaAgentId: string | null;
|
|
9
|
+
};
|
|
7
10
|
export declare function resolveRequestedWorkspaceId(requestedWorkspaceId: string | null | undefined): string | null;
|
|
11
|
+
export declare function resolveRequestedTelaAgentId(requestedTelaAgentId: string | null | undefined): string | null;
|
|
8
12
|
export declare function resolveChatContextFromSession(session: AppSession, requestedWorkspaceId?: string | null): ChatContext;
|
|
9
13
|
export declare function resolveChatContext(event: H3Event): ChatContext;
|
|
14
|
+
export declare function resolveChatRuntimeContext(event: H3Event): ChatRuntimeContext;
|
|
@@ -1,9 +1,22 @@
|
|
|
1
1
|
import { createError, getHeader } from "h3";
|
|
2
2
|
import { requireUser } from "#chat-runtime/server/utils/auth";
|
|
3
|
+
const TELA_AGENT_ID_PATTERN = /^[A-Za-z0-9_-]{1,128}$/;
|
|
3
4
|
export function resolveRequestedWorkspaceId(requestedWorkspaceId) {
|
|
4
5
|
const normalized = requestedWorkspaceId?.trim();
|
|
5
6
|
return normalized || null;
|
|
6
7
|
}
|
|
8
|
+
export function resolveRequestedTelaAgentId(requestedTelaAgentId) {
|
|
9
|
+
const normalized = requestedTelaAgentId?.trim();
|
|
10
|
+
if (!normalized)
|
|
11
|
+
return null;
|
|
12
|
+
if (!TELA_AGENT_ID_PATTERN.test(normalized)) {
|
|
13
|
+
throw createError({
|
|
14
|
+
statusCode: 400,
|
|
15
|
+
statusMessage: "Invalid Tela agent ID"
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
return normalized;
|
|
19
|
+
}
|
|
7
20
|
export function resolveChatContextFromSession(session, requestedWorkspaceId) {
|
|
8
21
|
const normalizedRequestedWorkspaceId = resolveRequestedWorkspaceId(requestedWorkspaceId);
|
|
9
22
|
if (normalizedRequestedWorkspaceId && normalizedRequestedWorkspaceId !== session.workspace.id) {
|
|
@@ -22,3 +35,10 @@ export function resolveChatContext(event) {
|
|
|
22
35
|
const requestedWorkspaceId = getHeader(event, "x-chat-workspace-id");
|
|
23
36
|
return resolveChatContextFromSession(session, requestedWorkspaceId);
|
|
24
37
|
}
|
|
38
|
+
export function resolveChatRuntimeContext(event) {
|
|
39
|
+
const context = resolveChatContext(event);
|
|
40
|
+
return {
|
|
41
|
+
...context,
|
|
42
|
+
telaAgentId: resolveRequestedTelaAgentId(getHeader(event, "x-chat-tela-agent-id"))
|
|
43
|
+
};
|
|
44
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { H3Event } from 'h3';
|
|
2
|
+
import { schema } from '#chat-runtime/server/db';
|
|
3
|
+
import type { useDb } from '#chat-runtime/server/db';
|
|
4
|
+
import type { ChatRuntimeContext } from '#chat-runtime/server/utils/chat-context';
|
|
5
|
+
import type { FileUploadInput, MessageFile } from '#chat-runtime/types/chat';
|
|
6
|
+
import type { AgentApiChatPayload, ContinueSessionPayload } from '#chat-runtime/types/agent';
|
|
7
|
+
import type { TelaAgentExecutionInput, TelaAgentRunPayload } from '#chat-runtime/types/tela-agent';
|
|
8
|
+
type DbInstance = ReturnType<typeof useDb>;
|
|
9
|
+
type ConversationRecord = typeof schema.conversations.$inferSelect;
|
|
10
|
+
type AgentTurnOperation = 'send' | 'retry';
|
|
11
|
+
type AgentTurnFiles = FileUploadInput[] | MessageFile[] | null | undefined;
|
|
12
|
+
export type PreparedDefaultAgentTurn = {
|
|
13
|
+
needsNewThread: boolean;
|
|
14
|
+
effectiveModel?: string;
|
|
15
|
+
settingsTimestamp: Date;
|
|
16
|
+
messageTitle: string;
|
|
17
|
+
createPayload: AgentApiChatPayload;
|
|
18
|
+
continuePayload: ContinueSessionPayload;
|
|
19
|
+
};
|
|
20
|
+
export declare function buildTelaAgentTurnPayload(event: H3Event, conversation: Pick<ConversationRecord, 'threadSessionId' | 'telaAgentId'>, content: string, files?: FileUploadInput[] | MessageFile[] | null, agentInputs?: TelaAgentExecutionInput[] | null): Promise<TelaAgentRunPayload>;
|
|
21
|
+
export declare function queueTelaAgentTurn(event: H3Event, db: DbInstance, options: {
|
|
22
|
+
conversation: ConversationRecord;
|
|
23
|
+
conversationId: string;
|
|
24
|
+
assistantMessageId: string;
|
|
25
|
+
payload: TelaAgentRunPayload;
|
|
26
|
+
titleContent: string;
|
|
27
|
+
operation: AgentTurnOperation;
|
|
28
|
+
}): void;
|
|
29
|
+
export declare function prepareDefaultAgentTurn(event: H3Event, db: DbInstance, context: ChatRuntimeContext, options: {
|
|
30
|
+
conversation: ConversationRecord;
|
|
31
|
+
conversationId: string;
|
|
32
|
+
content: string;
|
|
33
|
+
files?: AgentTurnFiles;
|
|
34
|
+
requestedModel?: string;
|
|
35
|
+
workspaceSettingsSnapshot?: unknown;
|
|
36
|
+
}): Promise<PreparedDefaultAgentTurn>;
|
|
37
|
+
export declare function resolveDefaultAgentEnvironmentVariables(event: H3Event, context: ChatRuntimeContext, logContext: Record<string, unknown>, failureMessage: string): Promise<Record<string, string>>;
|
|
38
|
+
export declare function withEnvironmentVariables(payload: AgentApiChatPayload, environmentVariables: Record<string, string>): AgentApiChatPayload;
|
|
39
|
+
export {};
|