diff --git a/packages/altair-api/src/ai/ai.service.ts b/packages/altair-api/src/ai/ai.service.ts
index 5f18db60f5..32bcffea49 100644
--- a/packages/altair-api/src/ai/ai.service.ts
+++ b/packages/altair-api/src/ai/ai.service.ts
@@ -16,6 +16,7 @@ import {
maxGraphqlVariablesChars,
maxMessageChars,
maxSdlChars,
+ responseMaxTokens,
} from 'altair-graphql-core/build/cjs/ai/constants';
import { ConfigService } from '@nestjs/config';
import { Config } from 'src/common/config';
@@ -220,54 +221,48 @@ export class AiService {
// https://platform.openai.com/docs/guides/prompt-engineering
const systemMessageParts = [
- 'I want you to act as a friendly and helpful expert of GraphQL and Altair GraphQL Client (https://altairgraphql.dev).',
- 'Only answer questions related to GraphQL and Altair GraphQL Client.',
- 'Be concise and clear in your responses.',
- 'Write your responses in markdown format.',
- 'Always wrap GraphQL queries in ```graphql``` code blocks.',
- ];
- // Use additional message context to enhance the system message
- if (messageInput.sdl) {
- systemMessageParts.push(dedent`
- Here is the SDL (schema) provided by the user:
+ dedent`You are an expert in GraphQL and Altair GraphQL Client (https://altairgraphql.dev). Your task is to answer user questions related to these topics professionally and concisely. Follow these instructions carefully:`,
+ dedent`1. First, review the provided SDL (Schema Definition Language):
- ${messageInput.sdl}
-
- `);
- }
- if (messageInput.graphqlQuery) {
- systemMessageParts.push(dedent`
- Here is the GraphQL query provided by the user:
-
- ${messageInput.graphqlQuery}
-
- `);
- }
- if (messageInput.graphqlVariables) {
- systemMessageParts.push(dedent`
- Here are the GraphQL variables (in JSON) provided by the user:
-
- ${messageInput.graphqlVariables}
-
- `);
- }
+ ${messageInput.sdl ?? ''}
+ `,
+ dedent`2. Next, examine the GraphQL query:
+
+ ${messageInput.graphqlQuery ?? ''}
+ `,
+ dedent`3. Then, look at the GraphQL variables (in JSON format):
+
+ ${messageInput.graphqlVariables ?? ''}
+ `,
+ dedent`4. When answering the user's question, follow these guidelines:
+ - Only answer questions related to GraphQL and Altair GraphQL Client.
+ - Focus solely on the topic the user is asking about.
+ - Provide enough information to guide the user in the right direction, but not necessarily a complete solution.
+ - Be respectful and professional in your responses.
+ - Keep your responses concise and clear, using no more than 3-4 sentences.
+ - Provide a maximum of 2 code snippets in your response, if necessary.
+ - Write your responses in markdown format.
+ - Always wrap GraphQL queries in \`\`\`graphql\`\`\` code blocks.
+ - If a sdl schema is provided, only generate GraphQL queries that are valid for the provided schema.`,
+ dedent`5. If you're unsure about something or need clarification, ask the user for more information.`,
+ dedent`6. If you're unable to answer a question, respond with: "I'm not sure about that, but I can try to help you with something else."`,
+ dedent`Now, please answer the following user question:`,
+ ];
const promptTemplate = ChatPromptTemplate.fromMessages([
- new SystemMessage(systemMessageParts.join('\n')),
+ new SystemMessage(systemMessageParts.join('\n\n')),
...previousMessages.map((m) => {
if (m.role === AiChatRole.USER) {
return new HumanMessage(m.message);
}
return new AIMessage(m.message);
}),
- new HumanMessage('{text}'),
+ new HumanMessage(`${messageInput.message}`),
]);
const chain = promptTemplate.pipe(model);
// Pass variables to invoke (variables are wrapped in curly braces)
- const response = await chain.invoke({
- text: messageInput.message,
- });
+ const response = await chain.invoke({});
const parser = new StringOutputParser();
const out = await parser.invoke(response);
return {
@@ -290,6 +285,7 @@ export class AiService {
return new ChatOpenAI({
apiKey: this.configService.get('ai.openai.apiKey', { infer: true }),
model: this.configService.get('ai.openai.model', { infer: true }),
+ maxTokens: responseMaxTokens,
});
}
case 'ollama': {
@@ -314,6 +310,7 @@ export class AiService {
return new ChatAnthropic({
apiKey: this.configService.get('ai.anthropic.apiKey', { infer: true }),
model: this.configService.get('ai.anthropic.model', { infer: true }),
+ maxTokens: responseMaxTokens,
});
}
}
diff --git a/packages/altair-api/src/logging/logging.interceptor.ts b/packages/altair-api/src/logging/logging.interceptor.ts
index e8e655969b..df0364da66 100644
--- a/packages/altair-api/src/logging/logging.interceptor.ts
+++ b/packages/altair-api/src/logging/logging.interceptor.ts
@@ -31,7 +31,7 @@ export class LoggingInterceptor implements NestInterceptor {
const now = Date.now();
return next.handle().pipe(
tap((x) => {
- tags.duration = Date.now() - now;
+ tags.duration = `${Date.now() - now}ms`;
this.logger.log(`POST: ${tagsToString(tags)}`);
})
);
diff --git a/packages/altair-core/src/ai/constants.ts b/packages/altair-core/src/ai/constants.ts
index a1f081afb7..fb0e0ac4d3 100644
--- a/packages/altair-core/src/ai/constants.ts
+++ b/packages/altair-core/src/ai/constants.ts
@@ -16,3 +16,5 @@ export const maxGraphqlQueryChars = maxGraphqlQueryTokens * avgCharsPerToken;
export const maxGraphqlVariablesTokens = 150;
export const maxGraphqlVariablesChars = maxGraphqlVariablesTokens * avgCharsPerToken;
+
+export const responseMaxTokens = 1000;
diff --git a/packages/altair-core/src/plugin/v3/parent-worker.ts b/packages/altair-core/src/plugin/v3/parent-worker.ts
index 4b458a1662..979ef6ad52 100644
--- a/packages/altair-core/src/plugin/v3/parent-worker.ts
+++ b/packages/altair-core/src/plugin/v3/parent-worker.ts
@@ -45,6 +45,7 @@ export class PluginParentWorker extends EvaluatorWorker {
iframe.style.width = '100%';
iframe.style.height = '100%';
iframe.style.border = 'none';
+ iframe.style.display = 'block'; // fixes issue with vertical scrollbar appearing https://stackoverflow.com/a/9131632/3929126
if ('width' in this.opts && this.opts.width) {
iframe.style.minWidth = `${this.opts.width}px`;
}
diff --git a/packages/altair-core/src/utils/logger.ts b/packages/altair-core/src/utils/logger.ts
index c291c816e7..593c15bb1b 100644
--- a/packages/altair-core/src/utils/logger.ts
+++ b/packages/altair-core/src/utils/logger.ts
@@ -16,6 +16,8 @@ export const createLogger = (environment: {
}): ILogger => {
if (!environment.production) {
loglevel.setLevel('TRACE');
+ } else {
+ loglevel.setLevel('ERROR');
}
const PREVIOUS_VERSION_KEY = 'altair__debug_previous_version';
@@ -45,6 +47,8 @@ export const createLogger = (environment: {
console.log('Current version:', currentVersion());
console.groupEnd();
loglevel.setLevel('TRACE');
+ } else {
+ loglevel.setLevel('ERROR');
}
(window as any)._ALTAIR__ENABLE_DEBUG_MODE__ = value;
},
diff --git a/plugins/ai/src/panel.tsx b/plugins/ai/src/panel.tsx
index d42bd393fc..4e346f83c0 100644
--- a/plugins/ai/src/panel.tsx
+++ b/plugins/ai/src/panel.tsx
@@ -43,8 +43,11 @@ const Panel = ({ context }: PanelProps) => {
});
const { data: messages, isLoading: messagesIsLoading } = useQuery({
- queryKey: ['sessionMessages'],
- queryFn: () => activeSession && context.getAiSessionMessages(activeSession.id),
+ queryKey: ['sessionMessages', activeSession?.id],
+ queryFn: () =>
+ activeSession
+ ? context.getAiSessionMessages(activeSession.id)
+ : Promise.resolve([]),
enabled: !!activeSession?.id,
});
@@ -52,9 +55,9 @@ const Panel = ({ context }: PanelProps) => {
{
mutationKey: ['createAiSession'],
mutationFn: () => context.createAiSession(),
- onSuccess: () => {
- queryClient.invalidateQueries({ queryKey: ['activeSession'] });
- queryClient.invalidateQueries({ queryKey: ['sessionMessages'] });
+ onSettled: async () => {
+ await queryClient.invalidateQueries({ queryKey: ['activeSession'] });
+ await queryClient.invalidateQueries({ queryKey: ['sessionMessages'] });
},
}
);
@@ -99,14 +102,15 @@ const Panel = ({ context }: PanelProps) => {
'sessionMessages',
]);
+ const sessionId = activeSession?.id ?? '';
const fakeMessage: IMessage = {
id: Math.random().toString(),
message: message,
role: 'USER',
- sessionId: activeSession?.id ?? '',
+ sessionId,
};
// Optimistically update to the new value
- queryClient.setQueryData(['sessionMessages'], (old) => [
+ queryClient.setQueryData(['sessionMessages', sessionId], (old) => [
...(old ?? []),
fakeMessage,
]);
diff --git a/test-server/src/schema/GOTBook.ts b/test-server/src/schema/GOTBook.ts
index 1d9ace50f3..c7165d4e82 100644
--- a/test-server/src/schema/GOTBook.ts
+++ b/test-server/src/schema/GOTBook.ts
@@ -1,4 +1,4 @@
-import axios from "axios";
+import axios from 'axios';
export const typeDef = `#graphql
extend type Query {