feat(api): add Lovart-style project and agent thread endpoints

Add canva/canda-compatible routes for lightweight project open/save and
agent thread history:
- POST /canva/project/queryProject, saveProject
- POST /canva/agent/queryAgentLastThread, agentThreadList
- GET /canda/chat-history, /canda/thread/status

Canvas save now accepts a compressed SHAKKERDATA:// snapshot payload,
preserves connections, and returns a SaveProject response; blank
successful image nodes are backfilled from generated artifacts. Frontend
designGateway adopts the new save/query flow.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-08 19:10:08 +08:00
parent ada29cee12
commit 263748af4a
27 changed files with 2045 additions and 114 deletions
+211 -8
View File
@@ -320,6 +320,11 @@ type ProjectIdRequest {
Id string `path:"id"`
}
type QueryProjectRequest {
ProjectId string `json:"projectId"`
Cid string `json:"cid,optional"`
}
type CreateProjectRequest {
Title string `json:"title,optional"`
Prompt string `json:"prompt,optional"`
@@ -338,6 +343,53 @@ type ProjectResponse {
Project Project `json:"project"`
}
type QueryProjectExtra {
PicCount int64 `json:"picCount"`
ProjectCoverList []string `json:"projectCoverList"`
}
type QueryProjectMeta {
UniqId string `json:"uniqId"`
ParentUniqId string `json:"parentUniqId"`
}
type QueryProjectAssetMeta {
AssetId string `json:"assetId"`
ProjectId string `json:"projectId"`
Name string `json:"name"`
ProjectType int64 `json:"projectType"`
ContentType string `json:"contentType"`
OwnerType string `json:"ownerType"`
OwnerId string `json:"ownerId"`
Extra QueryProjectExtra `json:"extra"`
Meta QueryProjectMeta `json:"meta"`
EffectivePermission string `json:"effectivePermission"`
CopyTaskStatus *string `json:"copyTaskStatus"`
Visibility string `json:"visibility"`
CreateTime string `json:"createTime"`
UpdateTime string `json:"updateTime"`
}
type QueryProjectData {
AssetMeta QueryProjectAssetMeta `json:"assetMeta"`
UserId string `json:"userId"`
ProjectName string `json:"projectName"`
ProjectId *string `json:"projectId"`
Canvas string `json:"canvas"`
ValidProjectId bool `json:"validProjectId"`
ProjectType int64 `json:"projectType"`
Version string `json:"version"`
SnapshotId *string `json:"snapshotId"`
ItemId *string `json:"itemId"`
Permission string `json:"permission"`
}
type QueryProjectResponse {
Code int64 `json:"code"`
Msg *string `json:"msg"`
Data QueryProjectData `json:"data"`
}
type DeleteProjectResponse {
Id string `json:"id"`
Deleted bool `json:"deleted"`
@@ -356,6 +408,105 @@ type ChatHistoryResponse {
Messages []AgentMessage `json:"messages"`
}
type QueryAgentLastThreadRequest {
ProjectId string `json:"projectId"`
Cid string `json:"cid,optional"`
}
type QueryAgentLastThreadResponse {
Code int64 `json:"code"`
Msg *string `json:"msg"`
Data string `json:"data"`
}
type AgentThreadListRequest {
ProjectId string `json:"projectId"`
Page int64 `json:"page,optional"`
PageSize int64 `json:"pageSize,optional"`
Cid string `json:"cid,optional"`
}
type LovartAgentThreadSummary {
Id int64 `json:"id"`
UserId string `json:"userId"`
ProjectId string `json:"projectId"`
AgentThreadId string `json:"agentThreadId"`
ThreadIdType int64 `json:"threadIdType"`
Title string `json:"title"`
Text string `json:"text"`
CoverImageUrl *string `json:"coverImageUrl"`
FileType *string `json:"fileType"`
UpdateTimestamp int64 `json:"updateTimestamp"`
Source int64 `json:"source"`
}
type LovartAgentThreadListData {
Page int64 `json:"page"`
Total int64 `json:"total"`
PageSize int64 `json:"pageSize"`
Data []LovartAgentThreadSummary `json:"data"`
UserIp string `json:"userIp"`
TraceId string `json:"traceId"`
HasMore bool `json:"hasMore"`
RankExpId *string `json:"rankExpId"`
AbVariant *string `json:"abVariant"`
}
type LovartAgentThreadListResponse {
Code int64 `json:"code"`
Msg *string `json:"msg"`
Data LovartAgentThreadListData `json:"data"`
}
type CandaChatHistoryRequest {
ThreadId string `form:"thread_id"`
ProjectId string `form:"project_id"`
}
type CandaThreadMeta {
ActionId string `json:"action_id"`
SessionId string `json:"session_id"`
StepId string `json:"step_id"`
Depth int64 `json:"depth"`
AgentName string `json:"agent_name"`
ProjectId string `json:"project_id"`
}
type CandaChatHistoryItem {
Id string `json:"id"`
Timestamp string `json:"timestamp"`
Type string `json:"type"`
ActionId string `json:"action_id"`
StepId string `json:"step_id"`
Text string `json:"text,optional"`
Content string `json:"content,optional"`
Status string `json:"status,optional"`
ToolCallId string `json:"tool_call_id,optional"`
Name string `json:"name,optional"`
ThreadMeta CandaThreadMeta `json:"thread_meta"`
}
type CandaChatHistoryResponse {
Code int64 `json:"code"`
Message string `json:"message"`
Data []CandaChatHistoryItem `json:"data"`
}
type CandaThreadStatusRequest {
ThreadId string `form:"thread_id"`
ProjectId string `form:"project_id,optional"`
}
type CandaThreadStatusData {
Status string `json:"status"`
}
type CandaThreadStatusResponse {
Code int64 `json:"code"`
Msg string `json:"msg"`
Data CandaThreadStatusData `json:"data"`
}
type GenerateRequest {
Id string `path:"id"`
Prompt string `json:"prompt"`
@@ -638,13 +789,47 @@ type MergeLayersRequest {
}
type SaveCanvasRequest {
Id string `path:"id"`
Version string `json:"version,optional"`
SnapshotId string `json:"snapshotId,optional"`
Canvas string `json:"canvas,optional"`
Viewport CanvasViewport `json:"viewport"`
Nodes []CanvasNode `json:"nodes"`
Connections []CanvasConnection `json:"connections"`
Id string `path:"id"`
Version string `json:"version,optional"`
SnapshotId string `json:"snapshotId,optional"`
Canvas string `json:"canvas,optional"`
Viewport CanvasViewport `json:"viewport,optional"`
Nodes []CanvasNode `json:"nodes,optional"`
Connections []CanvasConnection `json:"connections,optional"`
ProjectCoverList []string `json:"projectCoverList,optional"`
PicCount int64 `json:"picCount,optional"`
ProjectName string `json:"projectName,optional"`
ProjectId string `json:"projectId,optional"`
SessionId string `json:"sessionId,optional"`
CanvasV2Gray bool `json:"canvasV2Gray,optional"`
}
type SaveProjectRequest {
Canvas string `json:"canvas,optional"`
ProjectCoverList []string `json:"projectCoverList,optional"`
PicCount int64 `json:"picCount,optional"`
ProjectName string `json:"projectName,optional"`
ProjectId string `json:"projectId"`
Version string `json:"version,optional"`
SessionId string `json:"sessionId,optional"`
CanvasV2Gray bool `json:"canvasV2Gray,optional"`
SnapshotId string `json:"snapshotId,optional"`
Viewport CanvasViewport `json:"viewport,optional"`
Nodes []CanvasNode `json:"nodes,optional"`
Connections []CanvasConnection `json:"connections,optional"`
}
type SaveProjectData {
ProjectId string `json:"projectId"`
NewCreated bool `json:"newCreated"`
ValidProjectId bool `json:"validProjectId"`
Version string `json:"version"`
}
type SaveProjectResponse {
Code int64 `json:"code"`
Msg *string `json:"msg"`
Data SaveProjectData `json:"data"`
}
type CreateAssetUploadRequest {
@@ -732,6 +917,24 @@ service img_infinite_canvas-api {
@handler createProjectAsync
post /projects/async (CreateProjectRequest) returns (ProjectResponse)
@handler queryProject
post /canva/project/queryProject (QueryProjectRequest) returns (QueryProjectResponse)
@handler saveProject
post /canva/project/saveProject (SaveProjectRequest) returns (SaveProjectResponse)
@handler queryAgentLastThread
post /canva/agent/queryAgentLastThread (QueryAgentLastThreadRequest) returns (QueryAgentLastThreadResponse)
@handler agentThreadList
post /canva/agent/agentThreadList (AgentThreadListRequest) returns (LovartAgentThreadListResponse)
@handler candaChatHistory
get /canda/chat-history (CandaChatHistoryRequest) returns (CandaChatHistoryResponse)
@handler candaThreadStatus
get /canda/thread/status (CandaThreadStatusRequest) returns (CandaThreadStatusResponse)
@handler deleteProjects
delete /projects/batch-delete (DeleteProjectsRequest) returns (DeleteProjectsResponse)
@@ -802,7 +1005,7 @@ service img_infinite_canvas-api {
post /projects/:id/layers/merge (MergeLayersRequest) returns (ProjectResponse)
@handler saveCanvas
patch /projects/:id/canvas (SaveCanvasRequest) returns (ProjectResponse)
patch /projects/:id/canvas (SaveCanvasRequest) returns (SaveProjectResponse)
@handler createAssetUpload
post /assets/upload-url (CreateAssetUploadRequest) returns (CreateAssetUploadResponse)