Add thinking placeholder and improve location parameter handling

- Post '_Sea Haven Assistant is thinking..._' immediately on receipt,
  then update the message with the real response (chat.update)
- Broaden Maps location parameter description so agent passes facility
  names like 'Amazon BFI9' directly to Google Maps rather than asking
  the user to provide a street address
This commit is contained in:
Adam Moussa 2026-04-12 00:01:33 -04:00
parent 635e712966
commit 505b624242
2 changed files with 34 additions and 5 deletions

View file

@ -41,7 +41,7 @@ async function postToSlack(
channel: string,
text: string,
threadTs?: string,
): Promise<void> {
): Promise<string> {
const body: Record<string, string> = { channel, text };
if (threadTs) body.thread_ts = threadTs;
@ -55,8 +55,29 @@ async function postToSlack(
});
if (!res.ok) throw new Error(`Slack HTTP error ${res.status}`);
const data = (await res.json()) as { ok: boolean; error?: string };
const data = (await res.json()) as { ok: boolean; ts?: string; error?: string };
if (!data.ok) throw new Error(`Slack API error: ${data.error}`);
return data.ts!;
}
async function updateSlack(
token: string,
channel: string,
ts: string,
text: string,
): Promise<void> {
const res = await fetch('https://slack.com/api/chat.update', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${token}`,
},
body: JSON.stringify({ channel, ts, text }),
});
if (!res.ok) throw new Error(`Slack HTTP error ${res.status}`);
const data = (await res.json()) as { ok: boolean; error?: string };
if (!data.ok) throw new Error(`Slack update error: ${data.error}`);
}
// Reuse the most recent Bedrock session if there's been activity in the last 30 minutes.
@ -113,6 +134,14 @@ export const handler = async (event: ProcessorEvent): Promise<void> => {
resolveSessionId(userId),
]);
// Post placeholder immediately so the user sees a response while the agent thinks
const placeholderTs = await postToSlack(
credentials.botToken,
channelId,
'_Sea Haven Assistant is thinking..._',
threadTs ?? ts,
);
let answer: string;
try {
answer = await invokeAgent(sessionId, text);
@ -121,7 +150,7 @@ export const handler = async (event: ProcessorEvent): Promise<void> => {
answer = 'Sorry, I encountered an error processing your request. Please try again in a moment.';
}
await postToSlack(credentials.botToken, channelId, answer, threadTs ?? ts);
await updateSlack(credentials.botToken, channelId, placeholderTs, answer);
const now = new Date().toISOString();
const ttl = Math.floor(Date.now() / 1000) + 90 * 24 * 60 * 60; // 90-day TTL

View file

@ -189,7 +189,7 @@ Keep responses concise, professional, and actionable.`;
},
location: {
type: 'string',
description: 'City, address, or area to search near (e.g., "Seattle WA", "Chicago IL")',
description: 'Location to search near — can be a city, address, zip code, or facility/business name (e.g., "Seattle WA", "Amazon BFI9", "3230 International Pl DuPont WA"). Pass whatever location context the user provided; Google Maps will resolve it.',
required: true,
},
},
@ -205,7 +205,7 @@ Keep responses concise, professional, and actionable.`;
this.agentAlias = new bedrock.CfnAgentAlias(this, 'AgentAlias', {
agentId: this.agent.attrAgentId,
agentAliasName: 'live',
description: 'Production alias — seahaven-assistant v2 (Claude Sonnet 4.5)',
description: 'Production alias — seahaven-assistant v3 (flexible location lookup)',
});
}
}