refactor: update agent sync behavior, improve freshness detection patterns, and add diagnostic troubleshooting script
This commit is contained in:
@@ -26,6 +26,7 @@ Behavior rules:
|
||||
- Daily notes should include `focus`, `work-items`, and `blockers` when those values are clear.
|
||||
- Before answering a prompt that depends on current state, verify the latest relevant files instead of relying only on conversation history.
|
||||
- If the prompt asks for the latest Mattermost message, the last message from Jeff/current manager, or what someone just said, force a Mattermost refresh before answering and do not rely on stale inbox context.
|
||||
- Treat latest-message prompts as read-first: answer from refreshed evidence and report memory update candidates instead of editing canonical memory by default.
|
||||
- For learning-style questions, answer from known context and verified facts only; explicitly label unknowns, assumptions, and inferences.
|
||||
- For learning sessions, prioritize durable architecture, process, ownership, debugging strategy, release mechanics, domain concepts, and decision rules over transient ticket status.
|
||||
- If the user asks what to clarify, ask 3 to 5 high-leverage questions that would help a senior iOS engineer ramp into the project; include why each question matters.
|
||||
@@ -56,6 +57,7 @@ Behavior rules:
|
||||
- Do not wait for a dedicated sync command if the correct memory update is already obvious.
|
||||
- For analysis, drafting, review, or translation prompts, answer first and persist second unless saving the fact is required to produce the answer safely.
|
||||
- Avoid creating brand-new canonical notes in the middle of a response unless the user explicitly asked for persistence or the new note is the smallest correct update.
|
||||
- If a non-essential memory patch fails verification, stop retrying and return the answer plus the intended target file.
|
||||
- Do not leave behavior-only corrections only in daily logs. If a correction should affect future output, update the tool or instruction that produces that output.
|
||||
- If the memory interface or Obsidian adapter fails, continue with direct Markdown operations when safe and do not promote the failure as project memory.
|
||||
- Do not over-promote uncertain information. Keep uncertain items in the daily log.
|
||||
|
||||
@@ -13,6 +13,12 @@ function nowIso() {
|
||||
return new Date().toISOString()
|
||||
}
|
||||
|
||||
function envFlag(name, defaultValue = false) {
|
||||
const value = process.env[name]
|
||||
if (value === undefined) return defaultValue
|
||||
return ["1", "true", "yes", "on"].includes(value.trim().toLowerCase())
|
||||
}
|
||||
|
||||
async function resolveSyncCommand(directory) {
|
||||
const configured =
|
||||
process.env.AIW_MATTERMOST_SYNC_CMD?.trim() ||
|
||||
@@ -66,30 +72,16 @@ function requiresFreshMattermost(promptText) {
|
||||
.replace(/[\u0300-\u036f]/g, "")
|
||||
.toLowerCase()
|
||||
|
||||
const freshnessTerms = [
|
||||
"ultimo",
|
||||
"ultimos",
|
||||
"ultima",
|
||||
"ultimas",
|
||||
"latest",
|
||||
"last",
|
||||
"reciente",
|
||||
"recent",
|
||||
"nuevo",
|
||||
"new",
|
||||
"actualiza",
|
||||
"sync",
|
||||
"sincroniza",
|
||||
"revisa",
|
||||
"dijo",
|
||||
"menciono",
|
||||
"respondio",
|
||||
"contesto",
|
||||
"check",
|
||||
"look at",
|
||||
"said",
|
||||
"mentioned",
|
||||
"replied",
|
||||
const freshnessPatterns = [
|
||||
/\bultimo(?:s|a|as)?\s+(?:mensaje|mensajes|respuesta|respuestas|update|updates)\b/,
|
||||
/\bmensaje(?:s)?\s+(?:mas\s+)?reciente(?:s)?\b/,
|
||||
/\bque\s+(?:dijo|menciono|respondio|contesto)\b/,
|
||||
/\b(?:dijo|menciono|respondio|contesto)\s+(?:jeff|manager|supervisor)\b/,
|
||||
/\b(?:latest|last|recent)\s+(?:message|messages|reply|replies|update|updates)\b/,
|
||||
/\bwhat\s+did\s+.+\s+(?:say|mention|reply)\b/,
|
||||
/\b(?:said|mentioned|replied)\s+(?:jeff|manager|supervisor)\b/,
|
||||
/\b(?:sync|refresh|sincroniza|actualiza)\s+(?:mattermost|mensajes|messages|inbox)\b/,
|
||||
/\b(?:revisa|check|look\s+at)\s+(?:mattermost|mensajes|messages|inbox)\b/,
|
||||
]
|
||||
|
||||
const mattermostTerms = [
|
||||
@@ -123,10 +115,8 @@ function requiresFreshMattermost(promptText) {
|
||||
...configuredTerms,
|
||||
]
|
||||
|
||||
return (
|
||||
freshnessTerms.some((term) => text.includes(term)) &&
|
||||
return freshnessPatterns.some((pattern) => pattern.test(text)) &&
|
||||
sourceTerms.some((term) => text.includes(term))
|
||||
)
|
||||
}
|
||||
|
||||
export const MattermostInbox = async ({ $, directory, client }) => {
|
||||
@@ -152,6 +142,7 @@ export const MattermostInbox = async ({ $, directory, client }) => {
|
||||
|
||||
if (!options.force && now - lastSyncAt < minIntervalMs) return
|
||||
lastSyncAt = now
|
||||
const syncStartedAt = Date.now()
|
||||
|
||||
const inboxDir = path.join(directory, "ai/inbox")
|
||||
const latestPath = path.join(inboxDir, "mattermost-latest.md")
|
||||
@@ -179,6 +170,7 @@ export const MattermostInbox = async ({ $, directory, client }) => {
|
||||
|
||||
await writeStatus(statusPath, {
|
||||
syncedAt: nowIso(),
|
||||
durationMs: Date.now() - syncStartedAt,
|
||||
reason,
|
||||
forced: Boolean(options.force),
|
||||
changed: previous !== `${output}\n` && previous !== output,
|
||||
@@ -188,6 +180,7 @@ export const MattermostInbox = async ({ $, directory, client }) => {
|
||||
} else {
|
||||
await writeStatus(statusPath, {
|
||||
syncedAt: nowIso(),
|
||||
durationMs: Date.now() - syncStartedAt,
|
||||
reason,
|
||||
forced: Boolean(options.force),
|
||||
changed: false,
|
||||
@@ -199,6 +192,7 @@ export const MattermostInbox = async ({ $, directory, client }) => {
|
||||
} catch (error) {
|
||||
await writeStatus(statusPath, {
|
||||
syncedAt: nowIso(),
|
||||
durationMs: Date.now() - syncStartedAt,
|
||||
reason,
|
||||
forced: Boolean(options.force),
|
||||
changed: false,
|
||||
@@ -223,13 +217,20 @@ export const MattermostInbox = async ({ $, directory, client }) => {
|
||||
|
||||
return {
|
||||
event: async ({ event }) => {
|
||||
if (event.type === "session.created") {
|
||||
if (
|
||||
event.type === "session.created" &&
|
||||
envFlag("AIW_MATTERMOST_SYNC_ON_SESSION", false)
|
||||
) {
|
||||
await sync("session.created")
|
||||
}
|
||||
|
||||
if (event.type === "tui.prompt.append") {
|
||||
const promptText = extractPromptText(event)
|
||||
const forceFreshMattermost = requiresFreshMattermost(promptText)
|
||||
const allowPromptSync = envFlag("AIW_MATTERMOST_SYNC_ON_PROMPT", false)
|
||||
|
||||
if (!forceFreshMattermost && !allowPromptSync) return
|
||||
|
||||
await sync(
|
||||
forceFreshMattermost
|
||||
? "tui.prompt.append:fresh-mattermost-request"
|
||||
|
||||
Reference in New Issue
Block a user