thread-master/apps/backend/generate/api/studio.api

569 lines
17 KiB
Plaintext
Raw Normal View History

2026-07-13 01:15:30 +00:00
syntax = "v1"
// M4 Studio: personas / plays / outbox / compose / own-posts / mentions
type (
PersonaDraftPublic {
Identity string `json:"identity"`
Tone string `json:"tone"`
Audience string `json:"audience"`
Hooks string `json:"hooks"`
LanguageFingerprint string `json:"language_fingerprint"`
Rhythm string `json:"rhythm"`
Punctuation string `json:"punctuation"`
ContentPatterns string `json:"content_patterns"`
KnowledgeTranslation string `json:"knowledge_translation"`
CtaStyle string `json:"cta_style"`
Examples string `json:"examples"`
Avoid string `json:"avoid"`
}
StyleDimensionPublic {
Summary string `json:"summary"`
Evidence []string `json:"evidence,optional"`
}
PersonaStylePublic {
Draft PersonaDraftPublic `json:"draft"`
DraftText string `json:"draft_text"`
Source string `json:"source"`
BenchmarkUsername string `json:"benchmark_username,optional"`
SourceLabel string `json:"source_label,optional"`
SampleCount int `json:"sample_count"`
AnalyzedAt int64 `json:"analyzed_at,optional"`
SamplePreviews []string `json:"sample_previews,optional"`
// 8Dd1Tone…d8Risk → { summary, evidence }
Dimensions map[string]StyleDimensionPublic `json:"dimensions,optional"`
}
PersonaGuardPublic {
Avoid []string `json:"avoid"`
MaxChars int `json:"max_chars"`
BanAiTone bool `json:"ban_ai_tone"`
}
PersonaPublic {
Id string `json:"id"`
Name string `json:"name"`
Brief string `json:"brief"`
Status string `json:"status"`
Style PersonaStylePublic `json:"style"`
Guard PersonaGuardPublic `json:"guard"`
Voice string `json:"voice,optional"`
Notes string `json:"notes,optional"`
CreatedAt int64 `json:"created_at"`
UpdatedAt int64 `json:"updated_at"`
}
PersonaListData {
List []PersonaPublic `json:"list"`
}
PersonaSaveReq {
Id string `json:"id,optional"`
Name string `json:"name"`
Brief string `json:"brief,optional"`
Status string `json:"status,optional"`
Style PersonaStylePublic `json:"style,optional"`
Guard PersonaGuardPublic `json:"guard,optional"`
Voice string `json:"voice,optional"`
Notes string `json:"notes,optional"`
}
PersonaIdPath {
Id string `path:"id"`
}
PersonaActiveData {
Id string `json:"id"`
}
PersonaSetActiveReq {
Id string `json:"id"`
}
PersonaAnalyzeTextReq {
Id string `path:"id"`
RawText string `json:"raw_text"`
SourceLabel string `json:"source_label,optional"`
}
PersonaAnalyzeAccountReq {
Id string `path:"id"`
Username string `json:"username"`
}
// --- Plays ---
ExternalTargetPublic {
Url string `json:"url"`
RawUrl string `json:"raw_url,optional"`
Shortcode string `json:"shortcode,optional"`
AuthorUsername string `json:"author_username,optional"`
TextPreview string `json:"text_preview,optional"`
MediaId string `json:"media_id,optional"`
ResolvedAt int64 `json:"resolved_at,optional"`
}
PlayStepPublic {
Id string `json:"id"`
SortOrder int `json:"sort_order"`
Kind string `json:"kind"`
AccountId string `json:"account_id"`
Text string `json:"text"`
DelayFromPreviousSec int `json:"delay_from_previous_sec"`
PersonaId string `json:"persona_id,optional"`
BrandId string `json:"brand_id,optional"`
ImageUrls []string `json:"image_urls,optional"`
}
PlayPublic {
Id string `json:"id"`
Title string `json:"title"`
Topic string `json:"topic"`
Status string `json:"status"`
LeadAccountId string `json:"lead_account_id"`
CastAccountIds []string `json:"cast_account_ids"`
TargetOwnPostId string `json:"target_own_post_id,optional"`
TargetExternal ExternalTargetPublic `json:"target_external,optional"`
Steps []PlayStepPublic `json:"steps"`
ScheduleStartAt int64 `json:"schedule_start_at"`
IntervalMinutes int `json:"interval_minutes,optional"`
CreatedAt int64 `json:"created_at"`
UpdatedAt int64 `json:"updated_at"`
}
PlayListData {
List []PlayPublic `json:"list"`
}
PlaySaveReq {
Id string `json:"id,optional"`
Title string `json:"title"`
Topic string `json:"topic,optional"`
Status string `json:"status,optional"`
LeadAccountId string `json:"lead_account_id"`
CastAccountIds []string `json:"cast_account_ids,optional"`
TargetOwnPostId string `json:"target_own_post_id,optional"`
TargetExternal ExternalTargetPublic `json:"target_external,optional"`
Steps []PlayStepPublic `json:"steps"`
ScheduleStartAt int64 `json:"schedule_start_at,optional"`
IntervalMinutes int `json:"interval_minutes,optional"`
}
PlayIdPath {
Id string `path:"id"`
}
PlayByPostReq {
OwnPostId string `form:"own_post_id"`
}
PlayByExternalReq {
Url string `form:"url"`
}
PlayResolveReq {
Url string `json:"url"`
}
// AI 產劇本一步(真 LLM互回串場共用
PlayGenerateStepReq {
PersonaId string `json:"persona_id,optional"`
Context string `json:"context"` // 主貼/上一則/目標文
Topic string `json:"topic,optional"`
SpeakerLabel string `json:"speaker_label,optional"`
IsLead bool `json:"is_lead,optional"`
// mode: reply預設| root串場主貼
Mode string `json:"mode,optional"`
}
PlayGenerateStepData {
Text string `json:"text"`
}
// 一次產完整劇本(背景 job
PlayGenerateScriptData {
JobId string `json:"job_id"`
Async bool `json:"async"`
}
// --- Outbox ---
OutboxStepPublic {
Id string `json:"id"`
StepId string `json:"step_id"`
SortOrder int `json:"sort_order"`
Kind string `json:"kind"`
AccountId string `json:"account_id"`
Text string `json:"text"`
Status string `json:"status"`
Error string `json:"error,optional"`
ScheduledAt int64 `json:"scheduled_at,optional"`
PublishedAt int64 `json:"published_at,optional"`
}
OutboxPublic {
Id string `json:"id"`
PlayId string `json:"play_id"`
Title string `json:"title"`
Status string `json:"status"`
Steps []OutboxStepPublic `json:"steps"`
CreatedAt int64 `json:"created_at"`
UpdatedAt int64 `json:"updated_at"`
}
OutboxListData {
List []OutboxPublic `json:"list"`
}
OutboxIdPath {
Id string `path:"id"`
}
OutboxRetryPath {
Id string `path:"id"`
StepId string `path:"stepId"`
}
// --- Compose ---
ComposeMimicReq {
SourceText string `json:"source_text"`
PersonaId string `json:"persona_id,optional"`
// 可選:從「我的貼文」結構分析帶過來的備註(鉤子/結構/可複製點)
StructureNotes string `json:"structure_notes,optional"`
}
// 仿寫改背景 Job立刻回 job_id完成後從 job.payload.result_text 取文
ComposeMimicData {
// 相容同步路徑才有Job 路徑為空
Text string `json:"text,optional"`
JobId string `json:"job_id,optional"`
Async bool `json:"async,optional"`
}
// 人設試產:依指紋真 LLM 產主貼 + 回文(可帶新聞話題)
ComposePersonaPreviewReq {
PersonaId string `json:"persona_id"`
// 手動話題;空則嘗試上網取新聞靈感
Topic string `json:"topic,optional"`
// 預設 true無 topic 時抓即時新聞標題當靈感
UseNews bool `json:"use_news,optional"`
}
ComposePersonaPreviewData {
Topic string `json:"topic"`
TopicSource string `json:"topic_source"` // news | manual | fallback
PostText string `json:"post_text"`
ReplyText string `json:"reply_text"`
Notes string `json:"notes,optional"`
}
ComposeViralReq {
Text string `json:"text"`
}
ViralAnalysisPublic {
Hooks string `json:"hooks"`
Structure string `json:"structure"`
Emotion string `json:"emotion"`
Summary string `json:"summary"`
Cta string `json:"cta,optional"`
Copyable string `json:"copyable,optional"`
Risks string `json:"risks,optional"`
}
ComposePublishReq {
AccountId string `json:"account_id"`
Text string `json:"text"`
Title string `json:"title,optional"`
ImageUrls []string `json:"image_urls,optional"`
ScheduleStartAt int64 `json:"schedule_start_at,optional"`
// Threads 話題標籤topic_tag150 字,可不加 #
TopicTag string `json:"topic_tag,optional"`
}
// --- Own posts ---
OwnPostReplyPublic {
Id string `json:"id"`
Username string `json:"username"`
Text string `json:"text"`
CreatedAt int64 `json:"created_at"`
LikeCount int `json:"like_count,optional"`
ReplyStatus string `json:"reply_status,optional"`
RepliedBy string `json:"replied_by,optional"`
RepliedAt int64 `json:"replied_at,optional"`
ParentReplyId string `json:"parent_reply_id,optional"`
IsMine bool `json:"is_mine,optional"`
}
OwnPostPublic {
Id string `json:"id"`
AccountId string `json:"account_id"`
MediaId string `json:"media_id,optional"`
Text string `json:"text"`
MediaType string `json:"media_type"`
MediaUrl string `json:"media_url,optional"`
ThumbnailUrl string `json:"thumbnail_url,optional"`
Permalink string `json:"permalink,optional"`
Shortcode string `json:"shortcode,optional"`
TopicTag string `json:"topic_tag,optional"`
LikeCount int `json:"like_count"`
ReplyCount int `json:"reply_count"`
RepostCount int `json:"repost_count"`
QuoteCount int `json:"quote_count"`
ViewCount int `json:"view_count"`
ShareCount int `json:"share_count"`
InsightsStatus string `json:"insights_status,optional"`
FormulaSummary string `json:"formula_summary,optional"`
Insight string `json:"insight,optional"`
FormulaDetail string `json:"formula_detail,optional"`
Replies []OwnPostReplyPublic `json:"replies"`
PublishedAt int64 `json:"published_at"`
}
OwnPostListData {
List []OwnPostPublic `json:"list"`
}
OwnPostListReq {
AccountId string `form:"account_id,optional"`
}
OwnPostSyncReq {
AccountId string `json:"account_id"`
}
OwnPostLastSyncedData {
LastSyncedAt int64 `json:"last_synced_at"`
}
OwnPostGenerateReplyReq {
PostId string `json:"post_id"`
ReplyId string `json:"reply_id,optional"`
PersonaId string `json:"persona_id,optional"`
}
OwnPostGenerateReplyData {
Text string `json:"text"`
}
OwnPostSendReplyReq {
PostId string `json:"post_id"`
ReplyId string `json:"reply_id,optional"`
Text string `json:"text"`
AccountId string `json:"account_id,optional"`
ImageUrls []string `json:"image_urls,optional"`
}
OwnPostAnalyzeReq {
PostId string `json:"post_id"`
}
// 點開貼文後再載留言(避免 sync 一次打爆 conversation API
OwnPostLoadRepliesReq {
PostId string `json:"post_id"`
}
// --- Mentions ---
MentionPublic {
Id string `json:"id"`
AccountId string `json:"account_id"`
MediaId string `json:"media_id,optional"`
FromUsername string `json:"from_username"`
Text string `json:"text"`
ContextSnippet string `json:"context_snippet"`
Permalink string `json:"permalink,optional"`
Status string `json:"status"`
DraftText string `json:"draft_text,optional"`
CreatedAt int64 `json:"created_at"`
}
MentionListData {
List []MentionPublic `json:"list"`
}
MentionListReq {
AccountId string `form:"account_id,optional"`
}
MentionSyncReq {
AccountId string `json:"account_id"`
}
MentionIdPath {
Id string `path:"id"`
}
MentionGenerateReq {
Id string `path:"id"`
PersonaId string `json:"persona_id,optional"`
}
MentionMarkRepliedReq {
Id string `path:"id"`
Text string `json:"text,optional"`
ImageUrls []string `json:"image_urls,optional"`
}
)
@server (
jwt: Auth
group: personas
prefix: /api/v1/personas
middleware: AuthJWT
)
service gateway {
@handler ListPersonas
get / returns (PersonaListData)
@handler GetActivePersona
get /active returns (PersonaActiveData)
@handler SetActivePersona
post /active (PersonaSetActiveReq) returns (PersonaActiveData)
@handler GetPersona
get /:id (PersonaIdPath) returns (PersonaPublic)
@handler SavePersona
post / (PersonaSaveReq) returns (PersonaPublic)
@handler RemovePersona
delete /:id (PersonaIdPath) returns (OkData)
@handler AnalyzePersonaText
post /:id/analyze-text (PersonaAnalyzeTextReq) returns (PersonaPublic)
@handler AnalyzePersonaAccount
post /:id/analyze-account (PersonaAnalyzeAccountReq) returns (PersonaPublic)
}
@server (
jwt: Auth
group: plays
prefix: /api/v1/plays
middleware: AuthJWT
)
service gateway {
@handler ListPlays
get / returns (PlayListData)
@handler ListPlaysByPost
get /by-post (PlayByPostReq) returns (PlayListData)
@handler ListPlaysByExternal
get /by-external (PlayByExternalReq) returns (PlayListData)
@handler ResolveExternalLink
post /resolve-external (PlayResolveReq) returns (ExternalTargetPublic)
@handler GetPlay
get /:id (PlayIdPath) returns (PlayPublic)
@handler SavePlay
post / (PlaySaveReq) returns (PlayPublic)
@handler RemovePlay
delete /:id (PlayIdPath) returns (OkData)
@handler SubmitPlay
post /:id/submit (PlayIdPath) returns (OutboxPublic)
@handler GeneratePlayStep
post /generate-step (PlayGenerateStepReq) returns (PlayGenerateStepData)
@handler GeneratePlayScript
post /:id/generate-script (PlayIdPath) returns (PlayGenerateScriptData)
}
@server (
jwt: Auth
group: outbox
prefix: /api/v1/outbox
middleware: AuthJWT
)
service gateway {
@handler ListOutbox
get / returns (OutboxListData)
@handler GetOutbox
get /:id (OutboxIdPath) returns (OutboxPublic)
@handler RemoveOutbox
delete /:id (OutboxIdPath) returns (OkData)
@handler RetryOutboxStep
post /:id/steps/:stepId/retry (OutboxRetryPath) returns (OutboxPublic)
}
@server (
jwt: Auth
group: compose
prefix: /api/v1/compose
middleware: AuthJWT
)
service gateway {
@handler ComposeMimic
post /mimic (ComposeMimicReq) returns (ComposeMimicData)
@handler ComposePersonaPreview
post /persona-preview (ComposePersonaPreviewReq) returns (ComposePersonaPreviewData)
@handler ComposeAnalyzeViral
post /analyze-viral (ComposeViralReq) returns (ViralAnalysisPublic)
@handler ComposePublishSingle
post /publish-single (ComposePublishReq) returns (OutboxPublic)
}
@server (
jwt: Auth
group: ownposts
prefix: /api/v1/own-posts
middleware: AuthJWT
)
service gateway {
@handler ListOwnPosts
get / (OwnPostListReq) returns (OwnPostListData)
@handler OwnPostsLastSynced
get /last-synced-at returns (OwnPostLastSyncedData)
@handler SyncOwnPosts
post /sync (OwnPostSyncReq) returns (OwnPostListData)
@handler OwnPostGenerateReply
post /generate-reply (OwnPostGenerateReplyReq) returns (OwnPostGenerateReplyData)
@handler OwnPostSendReply
post /send-reply (OwnPostSendReplyReq) returns (OwnPostPublic)
@handler OwnPostAnalyze
post /analyze (OwnPostAnalyzeReq) returns (OwnPostPublic)
@handler OwnPostLoadReplies
post /load-replies (OwnPostLoadRepliesReq) returns (OwnPostPublic)
}
@server (
jwt: Auth
group: mentions
prefix: /api/v1/mentions
middleware: AuthJWT
)
service gateway {
@handler ListMentions
get / (MentionListReq) returns (MentionListData)
@handler SyncMentions
post /sync (MentionSyncReq) returns (MentionListData)
@handler MentionGenerateReply
post /:id/generate-reply (MentionGenerateReq) returns (MentionPublic)
@handler MentionMarkReplied
post /:id/mark-replied (MentionMarkRepliedReq) returns (MentionPublic)
@handler MentionSkip
post /:id/skip (MentionIdPath) returns (MentionPublic)
}