85 lines
3.1 KiB
TypeScript
85 lines
3.1 KiB
TypeScript
|
|
import type { ThreadsAccountData } from '../../types/api'
|
|||
|
|
import type { OnboardingSnapshot } from '../onboarding'
|
|||
|
|
import { detectActiveWorkflow } from '../placementFlow'
|
|||
|
|
import { formatSiteNavGuide } from './siteGuide'
|
|||
|
|
import { resolveIslanderPageMeta } from './pageRegistry'
|
|||
|
|
import { threadsAccountLabel } from '../threadsAccount'
|
|||
|
|
import { formatPlacementHandoffContext, getPlacementHandoff } from './handoffStore'
|
|||
|
|
import type { IslanderPageMeta } from './types'
|
|||
|
|
|
|||
|
|
type BuildContextInput = {
|
|||
|
|
pathname: string
|
|||
|
|
activeAccount: ThreadsAccountData | null
|
|||
|
|
onboarding: OnboardingSnapshot
|
|||
|
|
pageSnapshot?: string
|
|||
|
|
pageMeta?: IslanderPageMeta | null
|
|||
|
|
/** 僅在使用者主動問頁面/操作,或 agent 執行 action 後為 true */
|
|||
|
|
includePageDetail?: boolean
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const onboardingStepLabel = {
|
|||
|
|
account: '建立經營帳號',
|
|||
|
|
connection: '完成 Threads 連線',
|
|||
|
|
persona: '建立至少一個人設',
|
|||
|
|
} as const
|
|||
|
|
|
|||
|
|
export function buildIslanderContext(input: BuildContextInput): string {
|
|||
|
|
const includePage = input.includePageDetail === true
|
|||
|
|
const page = resolveIslanderPageMeta(input.pathname, input.pageMeta)
|
|||
|
|
const accountLabel = input.activeAccount ? threadsAccountLabel(input.activeAccount) : '(尚未選擇)'
|
|||
|
|
const publishPath = input.activeAccount
|
|||
|
|
? `/threads/${input.activeAccount.id}/publish`
|
|||
|
|
: '/settings'
|
|||
|
|
const connectionsPath = input.activeAccount
|
|||
|
|
? `/threads/${input.activeAccount.id}/connections`
|
|||
|
|
: '/settings'
|
|||
|
|
|
|||
|
|
const handoff = getPlacementHandoff()
|
|||
|
|
const handoffBlock = formatPlacementHandoffContext(handoff)
|
|||
|
|
const workflow = detectActiveWorkflow(input.pathname)
|
|||
|
|
const workflowLabel =
|
|||
|
|
workflow === 'copy'
|
|||
|
|
? '拷貝忍者(仿寫爆款,用人設 8D)'
|
|||
|
|
: workflow === 'placement'
|
|||
|
|
? '找 TA(品牌痛點獲客)'
|
|||
|
|
: '(非核心工作流頁)'
|
|||
|
|
|
|||
|
|
const sections = [
|
|||
|
|
'【目前位置】',
|
|||
|
|
`- 路徑:${input.pathname}`,
|
|||
|
|
`- 工作流:${workflowLabel}`,
|
|||
|
|
includePage
|
|||
|
|
? `- 頁面:${page.title}`
|
|||
|
|
: '- 頁面細節:使用者尚未詢問,請勿主動介紹這頁功能或元素',
|
|||
|
|
'',
|
|||
|
|
'【目前帳號】',
|
|||
|
|
`- 經營帳號:${accountLabel}`,
|
|||
|
|
`- 入門進度:${input.onboarding.isComplete ? '已完成' : input.onboarding.nextStep ? `進行中(${onboardingStepLabel[input.onboarding.nextStep]})` : '載入中'}`,
|
|||
|
|
'',
|
|||
|
|
'【常用捷徑】',
|
|||
|
|
`- 設定與 AI key → /settings`,
|
|||
|
|
`- 任務列表 → /jobs`,
|
|||
|
|
`- 人設庫 → /personas`,
|
|||
|
|
`- 發文 → ${publishPath}`,
|
|||
|
|
`- 連線細節 → ${connectionsPath}`,
|
|||
|
|
'',
|
|||
|
|
'【站內導覽】',
|
|||
|
|
formatSiteNavGuide(),
|
|||
|
|
handoffBlock,
|
|||
|
|
]
|
|||
|
|
|
|||
|
|
if (includePage) {
|
|||
|
|
sections.push(
|
|||
|
|
'',
|
|||
|
|
'【目前頁面】',
|
|||
|
|
page.purpose ? `- 用途:${page.purpose}` : '',
|
|||
|
|
page.hints?.length ? `- 提示:${page.hints.join(';')}` : '',
|
|||
|
|
'',
|
|||
|
|
'【目前頁面可互動元素】',
|
|||
|
|
'格式:ref | kind | label | meta(offscreen 表示需先 scroll)',
|
|||
|
|
input.pageSnapshot?.trim() || '(尚未擷取)',
|
|||
|
|
)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return sections.filter((line) => line !== '').join('\n')
|
|||
|
|
}
|