Atlas: opening message, isInit flag, strip trigger from history
- Add opening message instruction to atlas prompt - Handle isInit flag in atlasChat() to not store the greeting trigger as a user turn in conversation history - Update server.ts to pass is_init through to atlasChat() Made-with: Cursor
This commit is contained in:
@@ -73,6 +73,8 @@ export async function atlasChat(
|
|||||||
ctx: ToolContext,
|
ctx: ToolContext,
|
||||||
opts?: {
|
opts?: {
|
||||||
preloadedHistory?: LLMMessage[];
|
preloadedHistory?: LLMMessage[];
|
||||||
|
/** When true, the user message is an internal init trigger and should not be stored in history */
|
||||||
|
isInit?: boolean;
|
||||||
}
|
}
|
||||||
): Promise<AtlasChatResult> {
|
): Promise<AtlasChatResult> {
|
||||||
const llm = createLLM(process.env.ATLAS_MODEL ?? 'A', { temperature: 0.5 });
|
const llm = createLLM(process.env.ATLAS_MODEL ?? 'A', { temperature: 0.5 });
|
||||||
@@ -86,7 +88,10 @@ export async function atlasChat(
|
|||||||
const oaiTools = toOAITools(ATLAS_TOOLS);
|
const oaiTools = toOAITools(ATLAS_TOOLS);
|
||||||
const systemPrompt = resolvePrompt('atlas');
|
const systemPrompt = resolvePrompt('atlas');
|
||||||
|
|
||||||
|
// For init triggers, don't add the synthetic prompt as a user turn
|
||||||
|
if (!opts?.isInit) {
|
||||||
session.history.push({ role: 'user', content: userMessage });
|
session.history.push({ role: 'user', content: userMessage });
|
||||||
|
}
|
||||||
|
|
||||||
const buildMessages = (): LLMMessage[] => [
|
const buildMessages = (): LLMMessage[] => [
|
||||||
{ role: 'system', content: systemPrompt },
|
{ role: 'system', content: systemPrompt },
|
||||||
|
|||||||
@@ -151,4 +151,16 @@ The PRD should be specific enough that a technical team could implement it witho
|
|||||||
- **User is vague:** Offer options — "Let me give you three common approaches and you tell me which feels closest…"
|
- **User is vague:** Offer options — "Let me give you three common approaches and you tell me which feels closest…"
|
||||||
- **User changes direction mid-conversation:** Acknowledge the pivot and resurface downstream impacts.
|
- **User changes direction mid-conversation:** Acknowledge the pivot and resurface downstream impacts.
|
||||||
- **User asks about technical implementation:** "Great question — the platform handles the technical architecture automatically based on what we define here. What matters for the PRD is [reframe to product question]."
|
- **User asks about technical implementation:** "Great question — the platform handles the technical architecture automatically based on what we define here. What matters for the PRD is [reframe to product question]."
|
||||||
|
|
||||||
|
## Opening Message
|
||||||
|
|
||||||
|
When you receive an internal init trigger to begin a new conversation (no prior history), introduce yourself naturally:
|
||||||
|
|
||||||
|
"Hey! I'm Atlas — I'm here to help you turn your product idea into a clear, detailed requirements document that's ready for implementation.
|
||||||
|
|
||||||
|
Whether you've got a rough concept or a detailed spec that needs tightening, I'll walk you through the key decisions and make sure nothing important falls through the cracks.
|
||||||
|
|
||||||
|
So — what are we building?"
|
||||||
|
|
||||||
|
Do not mention that you received an internal trigger. Just deliver the opening message naturally.
|
||||||
`.trim());
|
`.trim());
|
||||||
|
|||||||
@@ -225,11 +225,13 @@ app.post('/atlas/chat', async (req: Request, res: Response) => {
|
|||||||
const {
|
const {
|
||||||
message,
|
message,
|
||||||
session_id,
|
session_id,
|
||||||
history
|
history,
|
||||||
|
is_init,
|
||||||
} = req.body as {
|
} = req.body as {
|
||||||
message?: string;
|
message?: string;
|
||||||
session_id?: string;
|
session_id?: string;
|
||||||
history?: LLMMessage[];
|
history?: LLMMessage[];
|
||||||
|
is_init?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!message) { res.status(400).json({ error: '"message" is required' }); return; }
|
if (!message) { res.status(400).json({ error: '"message" is required' }); return; }
|
||||||
@@ -238,7 +240,10 @@ app.post('/atlas/chat', async (req: Request, res: Response) => {
|
|||||||
const ctx = buildContext();
|
const ctx = buildContext();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const result = await atlasChat(sessionId, message, ctx, { preloadedHistory: history });
|
const result = await atlasChat(sessionId, message, ctx, {
|
||||||
|
preloadedHistory: history,
|
||||||
|
isInit: is_init,
|
||||||
|
});
|
||||||
res.json(result);
|
res.json(result);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
res.status(500).json({ error: err instanceof Error ? err.message : String(err) });
|
res.status(500).json({ error: err instanceof Error ? err.message : String(err) });
|
||||||
|
|||||||
Reference in New Issue
Block a user