@meistrari/chat-nuxt 1.5.1 → 1.7.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.
Files changed (46) hide show
  1. package/README.md +82 -0
  2. package/dist/module.json +1 -1
  3. package/dist/module.mjs +129 -3
  4. package/dist/runtime/components/MeistrariChatEmbed.vue +3 -0
  5. package/dist/runtime/components/chat/message-bubble.vue +2 -1
  6. package/dist/runtime/composables/useChat.js +4 -2
  7. package/dist/runtime/composables/useChatApi.js +6 -1
  8. package/dist/runtime/composables/useConversations.js +5 -2
  9. package/dist/runtime/composables/useEmbedConfig.d.ts +2 -0
  10. package/dist/runtime/composables/useEmbedConfig.js +5 -0
  11. package/dist/runtime/composables/useGitHubSkills.js +2 -1
  12. package/dist/runtime/composables/useWorkspaceExternalSkills.js +2 -1
  13. package/dist/runtime/composables/useWorkspaceMembers.js +2 -1
  14. package/dist/runtime/composables/useWorkspaceSettings.js +2 -1
  15. package/dist/runtime/composables/useWorkspaces.js +2 -1
  16. package/dist/runtime/embed/components/ChatEmbed.vue +7 -3
  17. package/dist/runtime/embed/components/ChatEmbedInner.vue +2 -1
  18. package/dist/runtime/internal/agent-environment-resolver.stub.d.ts +2 -0
  19. package/dist/runtime/internal/agent-environment-resolver.stub.js +1 -0
  20. package/dist/runtime/server/api/conversations/[id]/duplicate.post.js +1 -0
  21. package/dist/runtime/server/api/conversations/[id]/messages/[messageId]/retry.post.js +6 -2
  22. package/dist/runtime/server/api/conversations/[id]/messages/index.post.js +6 -2
  23. package/dist/runtime/server/api/conversations/index.post.js +1 -0
  24. package/dist/runtime/server/db/schema/conversations.d.ts +17 -0
  25. package/dist/runtime/server/db/schema/conversations.js +1 -0
  26. package/dist/runtime/server/utils/agent-api.js +4 -3
  27. package/dist/runtime/server/utils/agent-environment.d.ts +8 -0
  28. package/dist/runtime/server/utils/agent-environment.js +34 -0
  29. package/dist/runtime/server/utils/auth-token.d.ts +2 -0
  30. package/dist/runtime/server/utils/auth-token.js +21 -0
  31. package/dist/runtime/server/utils/chat-context.d.ts +2 -0
  32. package/dist/runtime/server/utils/chat-context.js +15 -1
  33. package/dist/runtime/server/utils/conversation-agent-turn.d.ts +6 -1
  34. package/dist/runtime/server/utils/conversation-agent-turn.js +27 -8
  35. package/dist/runtime/server/utils/conversation-scope.js +2 -1
  36. package/dist/runtime/server/utils/tela-api.js +2 -1
  37. package/dist/runtime/server/utils/workspace.js +3 -1
  38. package/dist/runtime/types/chat-agent-environment-resolver.d.ts +4 -0
  39. package/dist/runtime/types/chat-auth.d.ts +35 -0
  40. package/dist/runtime/types/embed.d.ts +19 -0
  41. package/dist/runtime/utils/tela-chat.d.ts +3 -1
  42. package/dist/runtime/utils/tela-chat.js +11 -2
  43. package/drizzle/0015_illegal_blindfold.sql +1 -0
  44. package/drizzle/meta/0015_snapshot.json +738 -0
  45. package/drizzle/meta/_journal.json +7 -0
  46. package/package.json +6 -1
@@ -30,6 +30,7 @@ export default defineEventHandler(async (event) => {
30
30
  userId: context.user.id,
31
31
  createdBy: context.user.email,
32
32
  telaAgentId: context.telaAgentId,
33
+ conversationScope: context.conversationScope,
33
34
  ...context.telaAgentId ? { model: null } : body.model ? { model: body.model } : {}
34
35
  }).returning();
35
36
  if (!conversation) {
@@ -105,6 +105,23 @@ export declare const conversations: import("drizzle-orm/pg-core").PgTableWithCol
105
105
  identity: undefined;
106
106
  generated: undefined;
107
107
  }, {}, {}>;
108
+ conversationScope: import("drizzle-orm/pg-core").PgColumn<{
109
+ name: "conversation_scope";
110
+ tableName: "conversations";
111
+ dataType: "string";
112
+ columnType: "PgText";
113
+ data: string;
114
+ driverParam: string;
115
+ notNull: false;
116
+ hasDefault: false;
117
+ isPrimaryKey: false;
118
+ isAutoincrement: false;
119
+ hasRuntimeDefault: false;
120
+ enumValues: [string, ...string[]];
121
+ baseColumn: never;
122
+ identity: undefined;
123
+ generated: undefined;
124
+ }, {}, {}>;
108
125
  model: import("drizzle-orm/pg-core").PgColumn<{
109
126
  name: "model";
110
127
  tableName: "conversations";
@@ -7,6 +7,7 @@ export const conversations = chatSchema.table("conversations", {
7
7
  title: text("title").notNull().default("Nova conversa"),
8
8
  threadSessionId: text("thread_session_id"),
9
9
  telaAgentId: text("tela_agent_id"),
10
+ conversationScope: text("conversation_scope"),
10
11
  model: text("model").default("claude-sonnet-4-5"),
11
12
  appliedSettingsAt: timestamp("applied_settings_at", { withTimezone: true }),
12
13
  appliedSettingsSnapshot: jsonb("applied_settings_snapshot").$type(),
@@ -2,11 +2,12 @@ import { createError } from "h3";
2
2
  import { useRuntimeConfig } from "nitropack/runtime";
3
3
  import { agentApiQueryResponseSchema, agentApiSessionSchema } from "#chat-runtime/types/agent";
4
4
  import { logger } from "#chat-runtime/server/utils/logger";
5
+ import { resolveAuthToken } from "#chat-runtime/server/utils/auth-token";
5
6
  const getConfig = () => useRuntimeConfig();
6
7
  export function getAgentDataToken(event) {
7
- const cookieToken = event.context.auth?.token;
8
- if (cookieToken) {
9
- return cookieToken;
8
+ const token = resolveAuthToken(event);
9
+ if (token) {
10
+ return token;
10
11
  }
11
12
  throw createError({
12
13
  statusCode: 401,
@@ -0,0 +1,8 @@
1
+ import type { H3Event } from 'h3';
2
+ import type { ChatRuntimeContext } from '#chat-runtime/server/utils/chat-context';
3
+ export type AgentEnvironmentResolverContext = ChatRuntimeContext & {
4
+ conversationId: string;
5
+ skills: readonly string[];
6
+ };
7
+ export type AgentEnvironmentVariables = Record<string, string>;
8
+ export declare function resolveHostAgentEnvironmentVariables(event: H3Event, context: AgentEnvironmentResolverContext, logContext: Record<string, unknown>): Promise<AgentEnvironmentVariables>;
@@ -0,0 +1,34 @@
1
+ import { z } from "zod";
2
+ import registeredAgentEnvironmentResolver from "#chat-agent-environment-resolver";
3
+ import { logger } from "#chat-runtime/server/utils/logger";
4
+ const agentEnvironmentVariablesSchema = z.record(z.string(), z.string()).nullable().optional();
5
+ function getRegisteredAgentEnvironmentResolver() {
6
+ const resolver = registeredAgentEnvironmentResolver;
7
+ return typeof resolver === "function" ? resolver : null;
8
+ }
9
+ function parseAgentEnvironmentVariables(value, logContext) {
10
+ const parsed = agentEnvironmentVariablesSchema.safeParse(value);
11
+ if (!parsed.success) {
12
+ logger.warn({
13
+ ...logContext,
14
+ issues: parsed.error.issues
15
+ }, "Agent environment resolver returned an invalid payload");
16
+ return {};
17
+ }
18
+ return parsed.data ?? {};
19
+ }
20
+ export async function resolveHostAgentEnvironmentVariables(event, context, logContext) {
21
+ const resolver = getRegisteredAgentEnvironmentResolver();
22
+ if (!resolver) {
23
+ return {};
24
+ }
25
+ try {
26
+ return parseAgentEnvironmentVariables(await resolver(event, context), logContext);
27
+ } catch (error) {
28
+ logger.warn({
29
+ ...logContext,
30
+ error
31
+ }, "Agent environment resolver failed, proceeding without host env vars");
32
+ return {};
33
+ }
34
+ }
@@ -0,0 +1,2 @@
1
+ import { type H3Event } from 'h3';
2
+ export declare function resolveAuthToken(event: H3Event): string | undefined;
@@ -0,0 +1,21 @@
1
+ import { getCookie } from "h3";
2
+ import { useRuntimeConfig } from "nitropack/runtime";
3
+ const DEFAULT_FIRST_PARTY_JWT_COOKIE_NAME = "tela-jwt";
4
+ function resolveFirstPartyJwtCookieName(event) {
5
+ const config = useRuntimeConfig(event);
6
+ return config.public?.telaAuth?.jwtCookieName || DEFAULT_FIRST_PARTY_JWT_COOKIE_NAME;
7
+ }
8
+ export function resolveAuthToken(event) {
9
+ const auth = event.context.auth;
10
+ if (auth?.token) {
11
+ return auth.token;
12
+ }
13
+ if (!auth?.user || !auth.workspace) {
14
+ return void 0;
15
+ }
16
+ const token = getCookie(event, resolveFirstPartyJwtCookieName(event));
17
+ if (token) {
18
+ auth.token = token;
19
+ }
20
+ return token;
21
+ }
@@ -6,9 +6,11 @@ export type ChatContext = {
6
6
  };
7
7
  export type ChatRuntimeContext = ChatContext & {
8
8
  telaAgentId: string | null;
9
+ conversationScope: string | null;
9
10
  };
10
11
  export declare function resolveRequestedWorkspaceId(requestedWorkspaceId: string | null | undefined): string | null;
11
12
  export declare function resolveRequestedTelaAgentId(requestedTelaAgentId: string | null | undefined): string | null;
13
+ export declare function resolveRequestedConversationScope(requestedConversationScope: string | null | undefined): string | null;
12
14
  export declare function resolveChatContextFromSession(session: AppSession, requestedWorkspaceId?: string | null): ChatContext;
13
15
  export declare function resolveChatContext(event: H3Event): ChatContext;
14
16
  export declare function resolveChatRuntimeContext(event: H3Event): ChatRuntimeContext;
@@ -1,6 +1,7 @@
1
1
  import { createError, getHeader } from "h3";
2
2
  import { requireUser } from "#chat-runtime/server/utils/auth";
3
3
  const TELA_AGENT_ID_PATTERN = /^[A-Za-z0-9_-]{1,128}$/;
4
+ const CONVERSATION_SCOPE_PATTERN = /^[A-Za-z0-9._:/-]{1,200}$/;
4
5
  export function resolveRequestedWorkspaceId(requestedWorkspaceId) {
5
6
  const normalized = requestedWorkspaceId?.trim();
6
7
  return normalized || null;
@@ -17,6 +18,18 @@ export function resolveRequestedTelaAgentId(requestedTelaAgentId) {
17
18
  }
18
19
  return normalized;
19
20
  }
21
+ export function resolveRequestedConversationScope(requestedConversationScope) {
22
+ const normalized = requestedConversationScope?.trim();
23
+ if (!normalized)
24
+ return null;
25
+ if (!CONVERSATION_SCOPE_PATTERN.test(normalized)) {
26
+ throw createError({
27
+ statusCode: 400,
28
+ statusMessage: "Invalid conversation scope"
29
+ });
30
+ }
31
+ return normalized;
32
+ }
20
33
  export function resolveChatContextFromSession(session, requestedWorkspaceId) {
21
34
  const normalizedRequestedWorkspaceId = resolveRequestedWorkspaceId(requestedWorkspaceId);
22
35
  if (normalizedRequestedWorkspaceId && normalizedRequestedWorkspaceId !== session.workspace.id) {
@@ -39,6 +52,7 @@ export function resolveChatRuntimeContext(event) {
39
52
  const context = resolveChatContext(event);
40
53
  return {
41
54
  ...context,
42
- telaAgentId: resolveRequestedTelaAgentId(getHeader(event, "x-chat-tela-agent-id"))
55
+ telaAgentId: resolveRequestedTelaAgentId(getHeader(event, "x-chat-tela-agent-id")),
56
+ conversationScope: resolveRequestedConversationScope(getHeader(event, "x-chat-conversation-scope"))
43
57
  };
44
58
  }
@@ -34,6 +34,11 @@ export declare function prepareDefaultAgentTurn(event: H3Event, db: DbInstance,
34
34
  requestedModel?: string;
35
35
  workspaceSettingsSnapshot?: unknown;
36
36
  }): Promise<PreparedDefaultAgentTurn>;
37
- export declare function resolveDefaultAgentEnvironmentVariables(event: H3Event, context: ChatRuntimeContext, logContext: Record<string, unknown>, failureMessage: string): Promise<Record<string, string>>;
37
+ export declare function resolveDefaultAgentEnvironmentVariables(event: H3Event, context: ChatRuntimeContext, options: {
38
+ conversationId: string;
39
+ skills?: readonly string[];
40
+ logContext: Record<string, unknown>;
41
+ credentialsFailureMessage: string;
42
+ }): Promise<Record<string, string>>;
38
43
  export declare function withEnvironmentVariables(payload: AgentApiChatPayload, environmentVariables: Record<string, string>): AgentApiChatPayload;
39
44
  export {};
@@ -2,6 +2,7 @@ import { and, eq, isNull } from "drizzle-orm";
2
2
  import { useRuntimeConfig } from "nitropack/runtime";
3
3
  import { schema } from "#chat-runtime/server/db";
4
4
  import { buildMessageWithContext, renderSystemPrompt, truncateTitle } from "#chat-runtime/server/utils/chat-message-builder";
5
+ import { resolveHostAgentEnvironmentVariables } from "#chat-runtime/server/utils/agent-environment";
5
6
  import {
6
7
  getConversationAppliedSettings,
7
8
  getWorkspaceSettingsUpdatedAt,
@@ -150,15 +151,33 @@ export async function prepareDefaultAgentTurn(event, db, context, options) {
150
151
  }
151
152
  };
152
153
  }
153
- export async function resolveDefaultAgentEnvironmentVariables(event, context, logContext, failureMessage) {
154
- if (!resolveChatNuxtFeatures(useRuntimeConfig()).credentials)
155
- return {};
156
- try {
157
- return await resolveWorkspaceCredentials(event, context.workspaceId);
158
- } catch (error) {
159
- logger.warn({ ...logContext, error }, failureMessage);
160
- return {};
154
+ export async function resolveDefaultAgentEnvironmentVariables(event, context, options) {
155
+ let credentialVariables = {};
156
+ const logContext = {
157
+ workspaceId: context.workspaceId,
158
+ conversationId: options.conversationId,
159
+ ...options.logContext
160
+ };
161
+ if (resolveChatNuxtFeatures(useRuntimeConfig()).credentials) {
162
+ try {
163
+ credentialVariables = await resolveWorkspaceCredentials(event, context.workspaceId);
164
+ } catch (error) {
165
+ logger.warn({ ...logContext, error }, options.credentialsFailureMessage);
166
+ }
161
167
  }
168
+ const hostVariables = await resolveHostAgentEnvironmentVariables(
169
+ event,
170
+ {
171
+ ...context,
172
+ conversationId: options.conversationId,
173
+ skills: options.skills ?? []
174
+ },
175
+ logContext
176
+ );
177
+ return {
178
+ ...credentialVariables,
179
+ ...hostVariables
180
+ };
162
181
  }
163
182
  export function withEnvironmentVariables(payload, environmentVariables) {
164
183
  if (Object.keys(environmentVariables).length === 0)
@@ -3,7 +3,8 @@ import { schema } from "#chat-runtime/server/db";
3
3
  export function conversationScopeConditions(context, conversationId) {
4
4
  const conditions = [
5
5
  eq(schema.conversations.workspaceId, context.workspaceId),
6
- context.telaAgentId ? eq(schema.conversations.telaAgentId, context.telaAgentId) : isNull(schema.conversations.telaAgentId)
6
+ context.telaAgentId ? eq(schema.conversations.telaAgentId, context.telaAgentId) : isNull(schema.conversations.telaAgentId),
7
+ context.conversationScope ? eq(schema.conversations.conversationScope, context.conversationScope) : isNull(schema.conversations.conversationScope)
7
8
  ];
8
9
  if (conversationId) {
9
10
  conditions.unshift(eq(schema.conversations.id, conversationId));
@@ -1,9 +1,10 @@
1
1
  import { createError } from "h3";
2
2
  import { useRuntimeConfig } from "nitropack/runtime";
3
3
  import { logger } from "#chat-runtime/server/utils/logger";
4
+ import { resolveAuthToken } from "#chat-runtime/server/utils/auth-token";
4
5
  export async function telaFetch(event, path, options) {
5
6
  const config = useRuntimeConfig();
6
- const token = event.context.auth?.token;
7
+ const token = resolveAuthToken(event);
7
8
  if (!token) {
8
9
  throw createError({ statusCode: 401, statusMessage: "No auth token" });
9
10
  }
@@ -1,6 +1,7 @@
1
1
  import { useRuntimeConfig } from "nitropack/runtime";
2
2
  import { eq } from "drizzle-orm";
3
3
  import { schema } from "#chat-runtime/server/db";
4
+ import { resolveAuthToken } from "#chat-runtime/server/utils/auth-token";
4
5
  import { telaFetch } from "#chat-runtime/server/utils/tela-api";
5
6
  export async function getWorkspaceSettings(db, workspaceId) {
6
7
  const [settings] = await db.select().from(schema.workspaceSettings).where(eq(schema.workspaceSettings.workspaceId, workspaceId));
@@ -8,6 +9,7 @@ export async function getWorkspaceSettings(db, workspaceId) {
8
9
  }
9
10
  export async function resolveWorkspaceCredentials(event, workspaceId) {
10
11
  const config = useRuntimeConfig();
12
+ const token = resolveAuthToken(event);
11
13
  return await telaFetch(
12
14
  event,
13
15
  `/workspaces/${workspaceId}/credentials/resolve`,
@@ -15,7 +17,7 @@ export async function resolveWorkspaceCredentials(event, workspaceId) {
15
17
  headers: {
16
18
  "X-Service-Name": "chat-app",
17
19
  "X-Service-Key": config.chatAppServiceKey,
18
- "x-data-token": event.context.auth?.token ?? ""
20
+ "x-data-token": token ?? ""
19
21
  }
20
22
  }
21
23
  ) ?? {};
@@ -0,0 +1,4 @@
1
+ declare module '#chat-agent-environment-resolver' {
2
+ const resolver: unknown
3
+ export default resolver
4
+ }
@@ -0,0 +1,35 @@
1
+ import type { Ref } from 'vue'
2
+
3
+ type ChatAuthUser = {
4
+ id: string
5
+ email?: string | null
6
+ name?: string | null
7
+ image?: string | null
8
+ }
9
+
10
+ type ChatAuthMemberUser = {
11
+ name: string
12
+ email: string
13
+ image?: string
14
+ }
15
+
16
+ type ChatAuthMember = {
17
+ id: string
18
+ userId: string
19
+ user: ChatAuthMemberUser
20
+ }
21
+
22
+ type ChatAuthOrganization = {
23
+ id: string
24
+ name?: string
25
+ logo?: string | null
26
+ members?: ChatAuthMember[]
27
+ }
28
+
29
+ export function useChatAuth(): {
30
+ user: Ref<ChatAuthUser | null>
31
+ activeOrganization: Ref<ChatAuthOrganization | null>
32
+ getToken: () => Promise<string | null | undefined>
33
+ getAvailableOrganizations: () => Promise<ChatAuthOrganization[]>
34
+ switchOrganization: (organizationId: string) => Promise<void>
35
+ }
@@ -4,26 +4,45 @@ import type { TelaAgentExecutionInput } from './tela-agent.js';
4
4
  import type { ChatLoadingMessageMode } from '../utils/chat-loading-messages.js';
5
5
  import type { ChatActor, ChatFeatureConfig } from '../utils/tela-chat.js';
6
6
  export type ChatEmbedSharedProps = {
7
+ /** Controlled conversation id. Use with `v-model:conversation-id` when the host owns active conversation state. */
7
8
  conversationId?: string | null;
9
+ /** Conversation id to open once on mount when `conversationId` is uncontrolled. */
8
10
  initialConversationId?: string | null;
11
+ /** Technical scope that isolates conversation history within the current workspace and runtime. */
12
+ conversationScope?: string | null;
13
+ /** Hide the conversation list and render only the active chat surface. */
9
14
  hideSidebar?: boolean;
15
+ /** Custom pending-response messages shown while the assistant is working. */
10
16
  loadingMessages?: readonly string[] | null;
17
+ /** How custom loading messages rotate. Defaults to ordered behavior when omitted. */
11
18
  loadingMessagesMode?: ChatLoadingMessageMode | null;
19
+ /** Custom markdown component renderers keyed by markdown node or tag name. */
12
20
  customComponents?: Record<string, Component>;
21
+ /** Extra HTML tags allowed by the markdown renderer. */
13
22
  customHtmlTags?: readonly string[];
14
23
  };
15
24
  export type DefaultChatEmbedProps = ChatEmbedSharedProps & {
25
+ /** Omitted in default chat mode. Set this to switch to Tela agent mode. */
16
26
  telaAgentId?: undefined;
27
+ /** Tela agent inputs are only accepted in Tela agent mode. */
17
28
  telaAgentInputs?: undefined;
29
+ /** Optional host-provided workspace settings. When omitted, chat-nuxt loads workspace settings itself. */
18
30
  workspaceSettings?: DeepReadonly<WorkspaceSettings> | WorkspaceSettings | null;
31
+ /** Optional display identity for messages created by the current user. */
19
32
  user?: ChatActor | null;
33
+ /** Optional UI feature toggles for the default chat runtime. */
20
34
  features?: Partial<ChatFeatureConfig>;
21
35
  };
22
36
  export type TelaAgentChatEmbedProps = ChatEmbedSharedProps & {
37
+ /** Tela agent id that switches the embed into Tela agent runtime mode. */
23
38
  telaAgentId: string;
39
+ /** Inputs sent with each Tela agent run. Non-null values hide the variables panel. */
24
40
  telaAgentInputs?: DeepReadonly<TelaAgentExecutionInput[]> | null;
41
+ /** Not accepted in Tela agent mode because the Tela agent owns runtime settings. */
25
42
  workspaceSettings?: never;
43
+ /** Not accepted in Tela agent mode because execution identity comes from the Tela agent runtime. */
26
44
  user?: never;
45
+ /** Optional UI feature toggles that are still supported in Tela agent mode. */
27
46
  features?: Partial<ChatFeatureConfig>;
28
47
  };
29
48
  export type MeistrariChatEmbedProps = DefaultChatEmbedProps | TelaAgentChatEmbedProps;
@@ -17,7 +17,9 @@ export type ChatActor = {
17
17
  };
18
18
  export declare function normalizeConversationId(value: string | null | undefined): string | null;
19
19
  export declare function normalizeTelaAgentId(value: string | null | undefined): string | null;
20
- export declare function resolveChatStateScope(workspaceId: string | null | undefined, telaAgentId: string | null | undefined): string;
20
+ export declare function normalizeConversationScope(value: string | null | undefined): string | null;
21
+ export declare function resolveConversationScopeKeySegment(value: string | null | undefined): string;
22
+ export declare function resolveChatStateScope(workspaceId: string | null | undefined, telaAgentId: string | null | undefined, conversationScope?: string | null): string;
21
23
  export declare function resolveChatFeatures(features?: Partial<ChatFeatureConfig>): ResolvedChatFeatureConfig;
22
24
  export declare function resolveConversationCreator(conversationUserId: string | null | undefined, options: {
23
25
  currentUser?: ChatActor | null;
@@ -9,10 +9,19 @@ export function normalizeTelaAgentId(value) {
9
9
  const normalized = value?.trim();
10
10
  return normalized || null;
11
11
  }
12
- export function resolveChatStateScope(workspaceId, telaAgentId) {
12
+ export function normalizeConversationScope(value) {
13
+ const normalized = value?.trim();
14
+ return normalized || null;
15
+ }
16
+ export function resolveConversationScopeKeySegment(value) {
17
+ const normalizedConversationScope = normalizeConversationScope(value);
18
+ return normalizedConversationScope ? `value:${normalizedConversationScope}` : "none";
19
+ }
20
+ export function resolveChatStateScope(workspaceId, telaAgentId, conversationScope) {
13
21
  const normalizedWorkspaceId = workspaceId?.trim() || "default";
14
22
  const normalizedTelaAgentId = normalizeTelaAgentId(telaAgentId);
15
- return normalizedTelaAgentId ? `${normalizedWorkspaceId}:tela-agent:${normalizedTelaAgentId}` : `${normalizedWorkspaceId}:default-chat`;
23
+ const runtimeScope = normalizedTelaAgentId ? `${normalizedWorkspaceId}:tela-agent:${normalizedTelaAgentId}` : `${normalizedWorkspaceId}:default-chat`;
24
+ return `${runtimeScope}:scope:${resolveConversationScopeKeySegment(conversationScope)}`;
16
25
  }
17
26
  export function resolveChatFeatures(features) {
18
27
  return {
@@ -0,0 +1 @@
1
+ ALTER TABLE "chat"."conversations" ADD COLUMN "conversation_scope" text;