mirror of
https://github.com/CherryHQ/cherry-studio.git
synced 2025-12-23 18:10:26 +08:00
Merge branch 'feat/agents-new' of github.com:CherryHQ/cherry-studio into feat/agents-new
This commit is contained in:
commit
ae9c78e643
@ -22,76 +22,114 @@ const agentsRouter = express.Router()
|
|||||||
* @swagger
|
* @swagger
|
||||||
* components:
|
* components:
|
||||||
* schemas:
|
* schemas:
|
||||||
|
* PermissionMode:
|
||||||
|
* type: string
|
||||||
|
* enum: [default, acceptEdits, bypassPermissions, plan]
|
||||||
|
* description: Permission mode for agent operations
|
||||||
|
*
|
||||||
|
* AgentType:
|
||||||
|
* type: string
|
||||||
|
* enum: [claude-code]
|
||||||
|
* description: Type of agent
|
||||||
|
*
|
||||||
|
* AgentConfiguration:
|
||||||
|
* type: object
|
||||||
|
* properties:
|
||||||
|
* permission_mode:
|
||||||
|
* $ref: '#/components/schemas/PermissionMode'
|
||||||
|
* default: default
|
||||||
|
* max_turns:
|
||||||
|
* type: integer
|
||||||
|
* default: 10
|
||||||
|
* description: Maximum number of interaction turns
|
||||||
|
* additionalProperties: true
|
||||||
|
*
|
||||||
|
* AgentBase:
|
||||||
|
* type: object
|
||||||
|
* properties:
|
||||||
|
* name:
|
||||||
|
* type: string
|
||||||
|
* description: Agent name
|
||||||
|
* description:
|
||||||
|
* type: string
|
||||||
|
* description: Agent description
|
||||||
|
* accessible_paths:
|
||||||
|
* type: array
|
||||||
|
* items:
|
||||||
|
* type: string
|
||||||
|
* description: Array of directory paths the agent can access
|
||||||
|
* instructions:
|
||||||
|
* type: string
|
||||||
|
* description: System prompt/instructions
|
||||||
|
* model:
|
||||||
|
* type: string
|
||||||
|
* description: Main model ID
|
||||||
|
* plan_model:
|
||||||
|
* type: string
|
||||||
|
* description: Optional planning model ID
|
||||||
|
* small_model:
|
||||||
|
* type: string
|
||||||
|
* description: Optional small/fast model ID
|
||||||
|
* mcps:
|
||||||
|
* type: array
|
||||||
|
* items:
|
||||||
|
* type: string
|
||||||
|
* description: Array of MCP tool IDs
|
||||||
|
* allowed_tools:
|
||||||
|
* type: array
|
||||||
|
* items:
|
||||||
|
* type: string
|
||||||
|
* description: Array of allowed tool IDs (whitelist)
|
||||||
|
* configuration:
|
||||||
|
* $ref: '#/components/schemas/AgentConfiguration'
|
||||||
|
* required:
|
||||||
|
* - model
|
||||||
|
* - accessible_paths
|
||||||
|
*
|
||||||
* AgentEntity:
|
* AgentEntity:
|
||||||
* type: object
|
* allOf:
|
||||||
* properties:
|
* - $ref: '#/components/schemas/AgentBase'
|
||||||
* id:
|
* - type: object
|
||||||
* type: string
|
* properties:
|
||||||
* description: Unique agent identifier
|
* id:
|
||||||
* name:
|
* type: string
|
||||||
* type: string
|
* description: Unique agent identifier
|
||||||
* description: Agent name
|
* type:
|
||||||
* description:
|
* $ref: '#/components/schemas/AgentType'
|
||||||
* type: string
|
* created_at:
|
||||||
* description: Agent description
|
* type: string
|
||||||
* avatar:
|
* format: date-time
|
||||||
* type: string
|
* description: ISO timestamp of creation
|
||||||
* description: Agent avatar URL
|
* updated_at:
|
||||||
* instructions:
|
* type: string
|
||||||
* type: string
|
* format: date-time
|
||||||
* description: System prompt/instructions
|
* description: ISO timestamp of last update
|
||||||
* model:
|
* required:
|
||||||
* type: string
|
* - id
|
||||||
* description: Main model ID
|
* - type
|
||||||
* plan_model:
|
* - created_at
|
||||||
* type: string
|
* - updated_at
|
||||||
* description: Optional planning model ID
|
|
||||||
* small_model:
|
|
||||||
* type: string
|
|
||||||
* description: Optional small/fast model ID
|
|
||||||
* built_in_tools:
|
|
||||||
* type: array
|
|
||||||
* items:
|
|
||||||
* type: string
|
|
||||||
* description: Built-in tool IDs
|
|
||||||
* mcps:
|
|
||||||
* type: array
|
|
||||||
* items:
|
|
||||||
* type: string
|
|
||||||
* description: MCP tool IDs
|
|
||||||
* knowledges:
|
|
||||||
* type: array
|
|
||||||
* items:
|
|
||||||
* type: string
|
|
||||||
* description: Knowledge base IDs
|
|
||||||
* configuration:
|
|
||||||
* type: object
|
|
||||||
* description: Extensible settings
|
|
||||||
* accessible_paths:
|
|
||||||
* type: array
|
|
||||||
* items:
|
|
||||||
* type: string
|
|
||||||
* description: Accessible directory paths
|
|
||||||
* permission_mode:
|
|
||||||
* type: string
|
|
||||||
* enum: [readOnly, acceptEdits, bypassPermissions]
|
|
||||||
* description: Permission mode
|
|
||||||
* max_steps:
|
|
||||||
* type: integer
|
|
||||||
* description: Maximum steps the agent can take
|
|
||||||
* created_at:
|
|
||||||
* type: string
|
|
||||||
* format: date-time
|
|
||||||
* updated_at:
|
|
||||||
* type: string
|
|
||||||
* format: date-time
|
|
||||||
* required:
|
|
||||||
* - id
|
|
||||||
* - name
|
|
||||||
* - model
|
|
||||||
* - created_at
|
|
||||||
* - updated_at
|
|
||||||
* CreateAgentRequest:
|
* CreateAgentRequest:
|
||||||
|
* allOf:
|
||||||
|
* - $ref: '#/components/schemas/AgentBase'
|
||||||
|
* - type: object
|
||||||
|
* properties:
|
||||||
|
* type:
|
||||||
|
* $ref: '#/components/schemas/AgentType'
|
||||||
|
* name:
|
||||||
|
* type: string
|
||||||
|
* minLength: 1
|
||||||
|
* description: Agent name (required)
|
||||||
|
* model:
|
||||||
|
* type: string
|
||||||
|
* minLength: 1
|
||||||
|
* description: Main model ID (required)
|
||||||
|
* required:
|
||||||
|
* - type
|
||||||
|
* - name
|
||||||
|
* - model
|
||||||
|
*
|
||||||
|
* UpdateAgentRequest:
|
||||||
* type: object
|
* type: object
|
||||||
* properties:
|
* properties:
|
||||||
* name:
|
* name:
|
||||||
@ -100,9 +138,11 @@ const agentsRouter = express.Router()
|
|||||||
* description:
|
* description:
|
||||||
* type: string
|
* type: string
|
||||||
* description: Agent description
|
* description: Agent description
|
||||||
* avatar:
|
* accessible_paths:
|
||||||
* type: string
|
* type: array
|
||||||
* description: Agent avatar URL
|
* items:
|
||||||
|
* type: string
|
||||||
|
* description: Array of directory paths the agent can access
|
||||||
* instructions:
|
* instructions:
|
||||||
* type: string
|
* type: string
|
||||||
* description: System prompt/instructions
|
* description: System prompt/instructions
|
||||||
@ -115,53 +155,409 @@ const agentsRouter = express.Router()
|
|||||||
* small_model:
|
* small_model:
|
||||||
* type: string
|
* type: string
|
||||||
* description: Optional small/fast model ID
|
* description: Optional small/fast model ID
|
||||||
* built_in_tools:
|
|
||||||
* type: array
|
|
||||||
* items:
|
|
||||||
* type: string
|
|
||||||
* description: Built-in tool IDs
|
|
||||||
* mcps:
|
* mcps:
|
||||||
* type: array
|
* type: array
|
||||||
* items:
|
* items:
|
||||||
* type: string
|
* type: string
|
||||||
* description: MCP tool IDs
|
* description: Array of MCP tool IDs
|
||||||
* knowledges:
|
* allowed_tools:
|
||||||
* type: array
|
* type: array
|
||||||
* items:
|
* items:
|
||||||
* type: string
|
* type: string
|
||||||
* description: Knowledge base IDs
|
* description: Array of allowed tool IDs (whitelist)
|
||||||
* configuration:
|
* configuration:
|
||||||
* type: object
|
* $ref: '#/components/schemas/AgentConfiguration'
|
||||||
* description: Extensible settings
|
* description: Partial update - all fields are optional
|
||||||
|
*
|
||||||
|
* ReplaceAgentRequest:
|
||||||
|
* $ref: '#/components/schemas/AgentBase'
|
||||||
|
*
|
||||||
|
* SessionEntity:
|
||||||
|
* allOf:
|
||||||
|
* - $ref: '#/components/schemas/AgentBase'
|
||||||
|
* - type: object
|
||||||
|
* properties:
|
||||||
|
* id:
|
||||||
|
* type: string
|
||||||
|
* description: Unique session identifier
|
||||||
|
* agent_id:
|
||||||
|
* type: string
|
||||||
|
* description: Primary agent ID for the session
|
||||||
|
* agent_type:
|
||||||
|
* $ref: '#/components/schemas/AgentType'
|
||||||
|
* created_at:
|
||||||
|
* type: string
|
||||||
|
* format: date-time
|
||||||
|
* description: ISO timestamp of creation
|
||||||
|
* updated_at:
|
||||||
|
* type: string
|
||||||
|
* format: date-time
|
||||||
|
* description: ISO timestamp of last update
|
||||||
|
* required:
|
||||||
|
* - id
|
||||||
|
* - agent_id
|
||||||
|
* - agent_type
|
||||||
|
* - created_at
|
||||||
|
* - updated_at
|
||||||
|
*
|
||||||
|
* CreateSessionRequest:
|
||||||
|
* allOf:
|
||||||
|
* - $ref: '#/components/schemas/AgentBase'
|
||||||
|
* - type: object
|
||||||
|
* properties:
|
||||||
|
* model:
|
||||||
|
* type: string
|
||||||
|
* minLength: 1
|
||||||
|
* description: Main model ID (required)
|
||||||
|
* required:
|
||||||
|
* - model
|
||||||
|
*
|
||||||
|
* UpdateSessionRequest:
|
||||||
|
* type: object
|
||||||
|
* properties:
|
||||||
|
* name:
|
||||||
|
* type: string
|
||||||
|
* description: Session name
|
||||||
|
* description:
|
||||||
|
* type: string
|
||||||
|
* description: Session description
|
||||||
* accessible_paths:
|
* accessible_paths:
|
||||||
* type: array
|
* type: array
|
||||||
* items:
|
* items:
|
||||||
* type: string
|
* type: string
|
||||||
* description: Accessible directory paths
|
* description: Array of directory paths the agent can access
|
||||||
* permission_mode:
|
* instructions:
|
||||||
* type: string
|
* type: string
|
||||||
* enum: [readOnly, acceptEdits, bypassPermissions]
|
* description: System prompt/instructions
|
||||||
* description: Permission mode
|
* model:
|
||||||
* max_steps:
|
* type: string
|
||||||
* type: integer
|
* description: Main model ID
|
||||||
* description: Maximum steps the agent can take
|
* plan_model:
|
||||||
|
* type: string
|
||||||
|
* description: Optional planning model ID
|
||||||
|
* small_model:
|
||||||
|
* type: string
|
||||||
|
* description: Optional small/fast model ID
|
||||||
|
* mcps:
|
||||||
|
* type: array
|
||||||
|
* items:
|
||||||
|
* type: string
|
||||||
|
* description: Array of MCP tool IDs
|
||||||
|
* allowed_tools:
|
||||||
|
* type: array
|
||||||
|
* items:
|
||||||
|
* type: string
|
||||||
|
* description: Array of allowed tool IDs (whitelist)
|
||||||
|
* configuration:
|
||||||
|
* $ref: '#/components/schemas/AgentConfiguration'
|
||||||
|
* description: Partial update - all fields are optional
|
||||||
|
*
|
||||||
|
* ReplaceSessionRequest:
|
||||||
|
* allOf:
|
||||||
|
* - $ref: '#/components/schemas/AgentBase'
|
||||||
|
* - type: object
|
||||||
|
* properties:
|
||||||
|
* model:
|
||||||
|
* type: string
|
||||||
|
* minLength: 1
|
||||||
|
* description: Main model ID (required)
|
||||||
|
* required:
|
||||||
|
* - model
|
||||||
|
*
|
||||||
|
* CreateSessionMessageRequest:
|
||||||
|
* type: object
|
||||||
|
* properties:
|
||||||
|
* content:
|
||||||
|
* type: string
|
||||||
|
* minLength: 1
|
||||||
|
* description: Message content
|
||||||
* required:
|
* required:
|
||||||
* - name
|
* - content
|
||||||
* - model
|
*
|
||||||
|
* PaginationQuery:
|
||||||
|
* type: object
|
||||||
|
* properties:
|
||||||
|
* limit:
|
||||||
|
* type: integer
|
||||||
|
* minimum: 1
|
||||||
|
* maximum: 100
|
||||||
|
* default: 20
|
||||||
|
* description: Number of items to return
|
||||||
|
* offset:
|
||||||
|
* type: integer
|
||||||
|
* minimum: 0
|
||||||
|
* default: 0
|
||||||
|
* description: Number of items to skip
|
||||||
|
* status:
|
||||||
|
* type: string
|
||||||
|
* enum: [idle, running, completed, failed, stopped]
|
||||||
|
* description: Filter by session status
|
||||||
|
*
|
||||||
|
* ListAgentsResponse:
|
||||||
|
* type: object
|
||||||
|
* properties:
|
||||||
|
* agents:
|
||||||
|
* type: array
|
||||||
|
* items:
|
||||||
|
* $ref: '#/components/schemas/AgentEntity'
|
||||||
|
* total:
|
||||||
|
* type: integer
|
||||||
|
* description: Total number of agents
|
||||||
|
* limit:
|
||||||
|
* type: integer
|
||||||
|
* description: Number of items returned
|
||||||
|
* offset:
|
||||||
|
* type: integer
|
||||||
|
* description: Number of items skipped
|
||||||
|
* required:
|
||||||
|
* - agents
|
||||||
|
* - total
|
||||||
|
* - limit
|
||||||
|
* - offset
|
||||||
|
*
|
||||||
|
* ListSessionsResponse:
|
||||||
|
* type: object
|
||||||
|
* properties:
|
||||||
|
* sessions:
|
||||||
|
* type: array
|
||||||
|
* items:
|
||||||
|
* $ref: '#/components/schemas/SessionEntity'
|
||||||
|
* total:
|
||||||
|
* type: integer
|
||||||
|
* description: Total number of sessions
|
||||||
|
* limit:
|
||||||
|
* type: integer
|
||||||
|
* description: Number of items returned
|
||||||
|
* offset:
|
||||||
|
* type: integer
|
||||||
|
* description: Number of items skipped
|
||||||
|
* required:
|
||||||
|
* - sessions
|
||||||
|
* - total
|
||||||
|
* - limit
|
||||||
|
* - offset
|
||||||
|
*
|
||||||
|
* ErrorResponse:
|
||||||
|
* type: object
|
||||||
|
* properties:
|
||||||
|
* error:
|
||||||
|
* type: object
|
||||||
|
* properties:
|
||||||
|
* message:
|
||||||
|
* type: string
|
||||||
|
* description: Error message
|
||||||
|
* type:
|
||||||
|
* type: string
|
||||||
|
* description: Error type
|
||||||
|
* code:
|
||||||
|
* type: string
|
||||||
|
* description: Error code
|
||||||
|
* required:
|
||||||
|
* - message
|
||||||
|
* - type
|
||||||
|
* - code
|
||||||
|
* required:
|
||||||
|
* - error
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @swagger
|
||||||
|
* /api/agents:
|
||||||
|
* post:
|
||||||
|
* summary: Create a new agent
|
||||||
|
* tags: [Agents]
|
||||||
|
* requestBody:
|
||||||
|
* required: true
|
||||||
|
* content:
|
||||||
|
* application/json:
|
||||||
|
* schema:
|
||||||
|
* $ref: '#/components/schemas/CreateAgentRequest'
|
||||||
|
* responses:
|
||||||
|
* 201:
|
||||||
|
* description: Agent created successfully
|
||||||
|
* content:
|
||||||
|
* application/json:
|
||||||
|
* schema:
|
||||||
|
* $ref: '#/components/schemas/AgentEntity'
|
||||||
|
* 400:
|
||||||
|
* description: Invalid request body
|
||||||
|
* content:
|
||||||
|
* application/json:
|
||||||
|
* schema:
|
||||||
|
* $ref: '#/components/schemas/ErrorResponse'
|
||||||
|
*/
|
||||||
// Agent CRUD routes
|
// Agent CRUD routes
|
||||||
agentsRouter.post('/', validateAgent, handleValidationErrors, agentHandlers.createAgent)
|
agentsRouter.post('/', validateAgent, handleValidationErrors, agentHandlers.createAgent)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @swagger
|
||||||
|
* /api/agents:
|
||||||
|
* get:
|
||||||
|
* summary: List all agents with pagination
|
||||||
|
* tags: [Agents]
|
||||||
|
* parameters:
|
||||||
|
* - in: query
|
||||||
|
* name: limit
|
||||||
|
* schema:
|
||||||
|
* type: integer
|
||||||
|
* minimum: 1
|
||||||
|
* maximum: 100
|
||||||
|
* default: 20
|
||||||
|
* description: Number of agents to return
|
||||||
|
* - in: query
|
||||||
|
* name: offset
|
||||||
|
* schema:
|
||||||
|
* type: integer
|
||||||
|
* minimum: 0
|
||||||
|
* default: 0
|
||||||
|
* description: Number of agents to skip
|
||||||
|
* - in: query
|
||||||
|
* name: status
|
||||||
|
* schema:
|
||||||
|
* type: string
|
||||||
|
* enum: [idle, running, completed, failed, stopped]
|
||||||
|
* description: Filter by agent status
|
||||||
|
* responses:
|
||||||
|
* 200:
|
||||||
|
* description: List of agents
|
||||||
|
* content:
|
||||||
|
* application/json:
|
||||||
|
* schema:
|
||||||
|
* $ref: '#/components/schemas/ListAgentsResponse'
|
||||||
|
*/
|
||||||
agentsRouter.get('/', validatePagination, handleValidationErrors, agentHandlers.listAgents)
|
agentsRouter.get('/', validatePagination, handleValidationErrors, agentHandlers.listAgents)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @swagger
|
||||||
|
* /api/agents/{agentId}:
|
||||||
|
* get:
|
||||||
|
* summary: Get agent by ID
|
||||||
|
* tags: [Agents]
|
||||||
|
* parameters:
|
||||||
|
* - in: path
|
||||||
|
* name: agentId
|
||||||
|
* required: true
|
||||||
|
* schema:
|
||||||
|
* type: string
|
||||||
|
* description: Agent ID
|
||||||
|
* responses:
|
||||||
|
* 200:
|
||||||
|
* description: Agent details
|
||||||
|
* content:
|
||||||
|
* application/json:
|
||||||
|
* schema:
|
||||||
|
* $ref: '#/components/schemas/AgentEntity'
|
||||||
|
* 404:
|
||||||
|
* description: Agent not found
|
||||||
|
* content:
|
||||||
|
* application/json:
|
||||||
|
* schema:
|
||||||
|
* $ref: '#/components/schemas/ErrorResponse'
|
||||||
|
*/
|
||||||
agentsRouter.get('/:agentId', validateAgentId, handleValidationErrors, agentHandlers.getAgent)
|
agentsRouter.get('/:agentId', validateAgentId, handleValidationErrors, agentHandlers.getAgent)
|
||||||
agentsRouter.put(
|
/**
|
||||||
'/:agentId',
|
* @swagger
|
||||||
validateAgentId,
|
* /api/agents/{agentId}:
|
||||||
validateAgentReplace,
|
* put:
|
||||||
handleValidationErrors,
|
* summary: Replace agent (full update)
|
||||||
agentHandlers.updateAgent
|
* tags: [Agents]
|
||||||
)
|
* parameters:
|
||||||
|
* - in: path
|
||||||
|
* name: agentId
|
||||||
|
* required: true
|
||||||
|
* schema:
|
||||||
|
* type: string
|
||||||
|
* description: Agent ID
|
||||||
|
* requestBody:
|
||||||
|
* required: true
|
||||||
|
* content:
|
||||||
|
* application/json:
|
||||||
|
* schema:
|
||||||
|
* $ref: '#/components/schemas/ReplaceAgentRequest'
|
||||||
|
* responses:
|
||||||
|
* 200:
|
||||||
|
* description: Agent updated successfully
|
||||||
|
* content:
|
||||||
|
* application/json:
|
||||||
|
* schema:
|
||||||
|
* $ref: '#/components/schemas/AgentEntity'
|
||||||
|
* 400:
|
||||||
|
* description: Invalid request body
|
||||||
|
* content:
|
||||||
|
* application/json:
|
||||||
|
* schema:
|
||||||
|
* $ref: '#/components/schemas/ErrorResponse'
|
||||||
|
* 404:
|
||||||
|
* description: Agent not found
|
||||||
|
* content:
|
||||||
|
* application/json:
|
||||||
|
* schema:
|
||||||
|
* $ref: '#/components/schemas/ErrorResponse'
|
||||||
|
*/
|
||||||
|
agentsRouter.put('/:agentId', validateAgentId, validateAgentReplace, handleValidationErrors, agentHandlers.updateAgent)
|
||||||
|
/**
|
||||||
|
* @swagger
|
||||||
|
* /api/agents/{agentId}:
|
||||||
|
* patch:
|
||||||
|
* summary: Update agent (partial update)
|
||||||
|
* tags: [Agents]
|
||||||
|
* parameters:
|
||||||
|
* - in: path
|
||||||
|
* name: agentId
|
||||||
|
* required: true
|
||||||
|
* schema:
|
||||||
|
* type: string
|
||||||
|
* description: Agent ID
|
||||||
|
* requestBody:
|
||||||
|
* required: true
|
||||||
|
* content:
|
||||||
|
* application/json:
|
||||||
|
* schema:
|
||||||
|
* $ref: '#/components/schemas/UpdateAgentRequest'
|
||||||
|
* responses:
|
||||||
|
* 200:
|
||||||
|
* description: Agent updated successfully
|
||||||
|
* content:
|
||||||
|
* application/json:
|
||||||
|
* schema:
|
||||||
|
* $ref: '#/components/schemas/AgentEntity'
|
||||||
|
* 400:
|
||||||
|
* description: Invalid request body
|
||||||
|
* content:
|
||||||
|
* application/json:
|
||||||
|
* schema:
|
||||||
|
* $ref: '#/components/schemas/ErrorResponse'
|
||||||
|
* 404:
|
||||||
|
* description: Agent not found
|
||||||
|
* content:
|
||||||
|
* application/json:
|
||||||
|
* schema:
|
||||||
|
* $ref: '#/components/schemas/ErrorResponse'
|
||||||
|
*/
|
||||||
agentsRouter.patch('/:agentId', validateAgentId, validateAgentUpdate, handleValidationErrors, agentHandlers.patchAgent)
|
agentsRouter.patch('/:agentId', validateAgentId, validateAgentUpdate, handleValidationErrors, agentHandlers.patchAgent)
|
||||||
|
/**
|
||||||
|
* @swagger
|
||||||
|
* /api/agents/{agentId}:
|
||||||
|
* delete:
|
||||||
|
* summary: Delete agent
|
||||||
|
* tags: [Agents]
|
||||||
|
* parameters:
|
||||||
|
* - in: path
|
||||||
|
* name: agentId
|
||||||
|
* required: true
|
||||||
|
* schema:
|
||||||
|
* type: string
|
||||||
|
* description: Agent ID
|
||||||
|
* responses:
|
||||||
|
* 204:
|
||||||
|
* description: Agent deleted successfully
|
||||||
|
* 404:
|
||||||
|
* description: Agent not found
|
||||||
|
* content:
|
||||||
|
* application/json:
|
||||||
|
* schema:
|
||||||
|
* $ref: '#/components/schemas/ErrorResponse'
|
||||||
|
*/
|
||||||
agentsRouter.delete('/:agentId', validateAgentId, handleValidationErrors, agentHandlers.deleteAgent)
|
agentsRouter.delete('/:agentId', validateAgentId, handleValidationErrors, agentHandlers.deleteAgent)
|
||||||
|
|
||||||
// Create sessions router with agent context
|
// Create sessions router with agent context
|
||||||
@ -169,9 +565,175 @@ const createSessionsRouter = (): express.Router => {
|
|||||||
const sessionsRouter = express.Router({ mergeParams: true })
|
const sessionsRouter = express.Router({ mergeParams: true })
|
||||||
|
|
||||||
// Session CRUD routes (nested under agent)
|
// Session CRUD routes (nested under agent)
|
||||||
|
/**
|
||||||
|
* @swagger
|
||||||
|
* /api/agents/{agentId}/sessions:
|
||||||
|
* post:
|
||||||
|
* summary: Create a new session for an agent
|
||||||
|
* tags: [Sessions]
|
||||||
|
* parameters:
|
||||||
|
* - in: path
|
||||||
|
* name: agentId
|
||||||
|
* required: true
|
||||||
|
* schema:
|
||||||
|
* type: string
|
||||||
|
* description: Agent ID
|
||||||
|
* requestBody:
|
||||||
|
* required: true
|
||||||
|
* content:
|
||||||
|
* application/json:
|
||||||
|
* schema:
|
||||||
|
* $ref: '#/components/schemas/CreateSessionRequest'
|
||||||
|
* responses:
|
||||||
|
* 201:
|
||||||
|
* description: Session created successfully
|
||||||
|
* content:
|
||||||
|
* application/json:
|
||||||
|
* schema:
|
||||||
|
* $ref: '#/components/schemas/SessionEntity'
|
||||||
|
* 400:
|
||||||
|
* description: Invalid request body
|
||||||
|
* content:
|
||||||
|
* application/json:
|
||||||
|
* schema:
|
||||||
|
* $ref: '#/components/schemas/ErrorResponse'
|
||||||
|
* 404:
|
||||||
|
* description: Agent not found
|
||||||
|
* content:
|
||||||
|
* application/json:
|
||||||
|
* schema:
|
||||||
|
* $ref: '#/components/schemas/ErrorResponse'
|
||||||
|
*/
|
||||||
sessionsRouter.post('/', validateSession, handleValidationErrors, sessionHandlers.createSession)
|
sessionsRouter.post('/', validateSession, handleValidationErrors, sessionHandlers.createSession)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @swagger
|
||||||
|
* /api/agents/{agentId}/sessions:
|
||||||
|
* get:
|
||||||
|
* summary: List sessions for an agent
|
||||||
|
* tags: [Sessions]
|
||||||
|
* parameters:
|
||||||
|
* - in: path
|
||||||
|
* name: agentId
|
||||||
|
* required: true
|
||||||
|
* schema:
|
||||||
|
* type: string
|
||||||
|
* description: Agent ID
|
||||||
|
* - in: query
|
||||||
|
* name: limit
|
||||||
|
* schema:
|
||||||
|
* type: integer
|
||||||
|
* minimum: 1
|
||||||
|
* maximum: 100
|
||||||
|
* default: 20
|
||||||
|
* description: Number of sessions to return
|
||||||
|
* - in: query
|
||||||
|
* name: offset
|
||||||
|
* schema:
|
||||||
|
* type: integer
|
||||||
|
* minimum: 0
|
||||||
|
* default: 0
|
||||||
|
* description: Number of sessions to skip
|
||||||
|
* - in: query
|
||||||
|
* name: status
|
||||||
|
* schema:
|
||||||
|
* type: string
|
||||||
|
* enum: [idle, running, completed, failed, stopped]
|
||||||
|
* description: Filter by session status
|
||||||
|
* responses:
|
||||||
|
* 200:
|
||||||
|
* description: List of sessions
|
||||||
|
* content:
|
||||||
|
* application/json:
|
||||||
|
* schema:
|
||||||
|
* $ref: '#/components/schemas/ListSessionsResponse'
|
||||||
|
* 404:
|
||||||
|
* description: Agent not found
|
||||||
|
* content:
|
||||||
|
* application/json:
|
||||||
|
* schema:
|
||||||
|
* $ref: '#/components/schemas/ErrorResponse'
|
||||||
|
*/
|
||||||
sessionsRouter.get('/', validatePagination, handleValidationErrors, sessionHandlers.listSessions)
|
sessionsRouter.get('/', validatePagination, handleValidationErrors, sessionHandlers.listSessions)
|
||||||
|
/**
|
||||||
|
* @swagger
|
||||||
|
* /api/agents/{agentId}/sessions/{sessionId}:
|
||||||
|
* get:
|
||||||
|
* summary: Get session by ID
|
||||||
|
* tags: [Sessions]
|
||||||
|
* parameters:
|
||||||
|
* - in: path
|
||||||
|
* name: agentId
|
||||||
|
* required: true
|
||||||
|
* schema:
|
||||||
|
* type: string
|
||||||
|
* description: Agent ID
|
||||||
|
* - in: path
|
||||||
|
* name: sessionId
|
||||||
|
* required: true
|
||||||
|
* schema:
|
||||||
|
* type: string
|
||||||
|
* description: Session ID
|
||||||
|
* responses:
|
||||||
|
* 200:
|
||||||
|
* description: Session details
|
||||||
|
* content:
|
||||||
|
* application/json:
|
||||||
|
* schema:
|
||||||
|
* $ref: '#/components/schemas/SessionEntity'
|
||||||
|
* 404:
|
||||||
|
* description: Agent or session not found
|
||||||
|
* content:
|
||||||
|
* application/json:
|
||||||
|
* schema:
|
||||||
|
* $ref: '#/components/schemas/ErrorResponse'
|
||||||
|
*/
|
||||||
sessionsRouter.get('/:sessionId', validateSessionId, handleValidationErrors, sessionHandlers.getSession)
|
sessionsRouter.get('/:sessionId', validateSessionId, handleValidationErrors, sessionHandlers.getSession)
|
||||||
|
/**
|
||||||
|
* @swagger
|
||||||
|
* /api/agents/{agentId}/sessions/{sessionId}:
|
||||||
|
* put:
|
||||||
|
* summary: Replace session (full update)
|
||||||
|
* tags: [Sessions]
|
||||||
|
* parameters:
|
||||||
|
* - in: path
|
||||||
|
* name: agentId
|
||||||
|
* required: true
|
||||||
|
* schema:
|
||||||
|
* type: string
|
||||||
|
* description: Agent ID
|
||||||
|
* - in: path
|
||||||
|
* name: sessionId
|
||||||
|
* required: true
|
||||||
|
* schema:
|
||||||
|
* type: string
|
||||||
|
* description: Session ID
|
||||||
|
* requestBody:
|
||||||
|
* required: true
|
||||||
|
* content:
|
||||||
|
* application/json:
|
||||||
|
* schema:
|
||||||
|
* $ref: '#/components/schemas/ReplaceSessionRequest'
|
||||||
|
* responses:
|
||||||
|
* 200:
|
||||||
|
* description: Session updated successfully
|
||||||
|
* content:
|
||||||
|
* application/json:
|
||||||
|
* schema:
|
||||||
|
* $ref: '#/components/schemas/SessionEntity'
|
||||||
|
* 400:
|
||||||
|
* description: Invalid request body
|
||||||
|
* content:
|
||||||
|
* application/json:
|
||||||
|
* schema:
|
||||||
|
* $ref: '#/components/schemas/ErrorResponse'
|
||||||
|
* 404:
|
||||||
|
* description: Agent or session not found
|
||||||
|
* content:
|
||||||
|
* application/json:
|
||||||
|
* schema:
|
||||||
|
* $ref: '#/components/schemas/ErrorResponse'
|
||||||
|
*/
|
||||||
sessionsRouter.put(
|
sessionsRouter.put(
|
||||||
'/:sessionId',
|
'/:sessionId',
|
||||||
validateSessionId,
|
validateSessionId,
|
||||||
@ -179,6 +741,51 @@ const createSessionsRouter = (): express.Router => {
|
|||||||
handleValidationErrors,
|
handleValidationErrors,
|
||||||
sessionHandlers.updateSession
|
sessionHandlers.updateSession
|
||||||
)
|
)
|
||||||
|
/**
|
||||||
|
* @swagger
|
||||||
|
* /api/agents/{agentId}/sessions/{sessionId}:
|
||||||
|
* patch:
|
||||||
|
* summary: Update session (partial update)
|
||||||
|
* tags: [Sessions]
|
||||||
|
* parameters:
|
||||||
|
* - in: path
|
||||||
|
* name: agentId
|
||||||
|
* required: true
|
||||||
|
* schema:
|
||||||
|
* type: string
|
||||||
|
* description: Agent ID
|
||||||
|
* - in: path
|
||||||
|
* name: sessionId
|
||||||
|
* required: true
|
||||||
|
* schema:
|
||||||
|
* type: string
|
||||||
|
* description: Session ID
|
||||||
|
* requestBody:
|
||||||
|
* required: true
|
||||||
|
* content:
|
||||||
|
* application/json:
|
||||||
|
* schema:
|
||||||
|
* $ref: '#/components/schemas/UpdateSessionRequest'
|
||||||
|
* responses:
|
||||||
|
* 200:
|
||||||
|
* description: Session updated successfully
|
||||||
|
* content:
|
||||||
|
* application/json:
|
||||||
|
* schema:
|
||||||
|
* $ref: '#/components/schemas/SessionEntity'
|
||||||
|
* 400:
|
||||||
|
* description: Invalid request body
|
||||||
|
* content:
|
||||||
|
* application/json:
|
||||||
|
* schema:
|
||||||
|
* $ref: '#/components/schemas/ErrorResponse'
|
||||||
|
* 404:
|
||||||
|
* description: Agent or session not found
|
||||||
|
* content:
|
||||||
|
* application/json:
|
||||||
|
* schema:
|
||||||
|
* $ref: '#/components/schemas/ErrorResponse'
|
||||||
|
*/
|
||||||
sessionsRouter.patch(
|
sessionsRouter.patch(
|
||||||
'/:sessionId',
|
'/:sessionId',
|
||||||
validateSessionId,
|
validateSessionId,
|
||||||
@ -186,6 +793,35 @@ const createSessionsRouter = (): express.Router => {
|
|||||||
handleValidationErrors,
|
handleValidationErrors,
|
||||||
sessionHandlers.patchSession
|
sessionHandlers.patchSession
|
||||||
)
|
)
|
||||||
|
/**
|
||||||
|
* @swagger
|
||||||
|
* /api/agents/{agentId}/sessions/{sessionId}:
|
||||||
|
* delete:
|
||||||
|
* summary: Delete session
|
||||||
|
* tags: [Sessions]
|
||||||
|
* parameters:
|
||||||
|
* - in: path
|
||||||
|
* name: agentId
|
||||||
|
* required: true
|
||||||
|
* schema:
|
||||||
|
* type: string
|
||||||
|
* description: Agent ID
|
||||||
|
* - in: path
|
||||||
|
* name: sessionId
|
||||||
|
* required: true
|
||||||
|
* schema:
|
||||||
|
* type: string
|
||||||
|
* description: Session ID
|
||||||
|
* responses:
|
||||||
|
* 204:
|
||||||
|
* description: Session deleted successfully
|
||||||
|
* 404:
|
||||||
|
* description: Agent or session not found
|
||||||
|
* content:
|
||||||
|
* application/json:
|
||||||
|
* schema:
|
||||||
|
* $ref: '#/components/schemas/ErrorResponse'
|
||||||
|
*/
|
||||||
sessionsRouter.delete('/:sessionId', validateSessionId, handleValidationErrors, sessionHandlers.deleteSession)
|
sessionsRouter.delete('/:sessionId', validateSessionId, handleValidationErrors, sessionHandlers.deleteSession)
|
||||||
|
|
||||||
return sessionsRouter
|
return sessionsRouter
|
||||||
@ -196,6 +832,77 @@ const createMessagesRouter = (): express.Router => {
|
|||||||
const messagesRouter = express.Router({ mergeParams: true })
|
const messagesRouter = express.Router({ mergeParams: true })
|
||||||
|
|
||||||
// Message CRUD routes (nested under agent/session)
|
// Message CRUD routes (nested under agent/session)
|
||||||
|
/**
|
||||||
|
* @swagger
|
||||||
|
* /api/agents/{agentId}/sessions/{sessionId}/messages:
|
||||||
|
* post:
|
||||||
|
* summary: Create a new message in a session
|
||||||
|
* tags: [Messages]
|
||||||
|
* parameters:
|
||||||
|
* - in: path
|
||||||
|
* name: agentId
|
||||||
|
* required: true
|
||||||
|
* schema:
|
||||||
|
* type: string
|
||||||
|
* description: Agent ID
|
||||||
|
* - in: path
|
||||||
|
* name: sessionId
|
||||||
|
* required: true
|
||||||
|
* schema:
|
||||||
|
* type: string
|
||||||
|
* description: Session ID
|
||||||
|
* requestBody:
|
||||||
|
* required: true
|
||||||
|
* content:
|
||||||
|
* application/json:
|
||||||
|
* schema:
|
||||||
|
* $ref: '#/components/schemas/CreateSessionMessageRequest'
|
||||||
|
* responses:
|
||||||
|
* 201:
|
||||||
|
* description: Message created successfully
|
||||||
|
* content:
|
||||||
|
* application/json:
|
||||||
|
* schema:
|
||||||
|
* type: object
|
||||||
|
* properties:
|
||||||
|
* id:
|
||||||
|
* type: number
|
||||||
|
* description: Message ID
|
||||||
|
* session_id:
|
||||||
|
* type: string
|
||||||
|
* description: Session ID
|
||||||
|
* role:
|
||||||
|
* type: string
|
||||||
|
* enum: [assistant, user, system, tool]
|
||||||
|
* description: Message role
|
||||||
|
* content:
|
||||||
|
* type: object
|
||||||
|
* description: Message content (AI SDK format)
|
||||||
|
* agent_session_id:
|
||||||
|
* type: string
|
||||||
|
* description: Agent session ID for resuming
|
||||||
|
* metadata:
|
||||||
|
* type: object
|
||||||
|
* description: Additional metadata
|
||||||
|
* created_at:
|
||||||
|
* type: string
|
||||||
|
* format: date-time
|
||||||
|
* updated_at:
|
||||||
|
* type: string
|
||||||
|
* format: date-time
|
||||||
|
* 400:
|
||||||
|
* description: Invalid request body
|
||||||
|
* content:
|
||||||
|
* application/json:
|
||||||
|
* schema:
|
||||||
|
* $ref: '#/components/schemas/ErrorResponse'
|
||||||
|
* 404:
|
||||||
|
* description: Agent or session not found
|
||||||
|
* content:
|
||||||
|
* application/json:
|
||||||
|
* schema:
|
||||||
|
* $ref: '#/components/schemas/ErrorResponse'
|
||||||
|
*/
|
||||||
messagesRouter.post('/', validateSessionMessage, handleValidationErrors, messageHandlers.createMessage)
|
messagesRouter.post('/', validateSessionMessage, handleValidationErrors, messageHandlers.createMessage)
|
||||||
return messagesRouter
|
return messagesRouter
|
||||||
}
|
}
|
||||||
|
|||||||
@ -9,7 +9,7 @@ import type {
|
|||||||
} from '@types'
|
} from '@types'
|
||||||
import { ModelMessage, UIMessage, UIMessageChunk } from 'ai'
|
import { ModelMessage, UIMessage, UIMessageChunk } from 'ai'
|
||||||
import { convertToModelMessages, readUIMessageStream } from 'ai'
|
import { convertToModelMessages, readUIMessageStream } from 'ai'
|
||||||
import { eq } from 'drizzle-orm'
|
import { desc, eq } from 'drizzle-orm'
|
||||||
|
|
||||||
import { BaseService } from '../BaseService'
|
import { BaseService } from '../BaseService'
|
||||||
import { InsertSessionMessageRow, sessionMessagesTable } from '../database/schema'
|
import { InsertSessionMessageRow, sessionMessagesTable } from '../database/schema'
|
||||||
@ -170,29 +170,6 @@ export class SessionMessageService extends BaseService {
|
|||||||
return { messages }
|
return { messages }
|
||||||
}
|
}
|
||||||
|
|
||||||
async saveUserMessage(
|
|
||||||
tx: any,
|
|
||||||
sessionId: string,
|
|
||||||
prompt: string,
|
|
||||||
agentSessionId: string
|
|
||||||
): Promise<AgentSessionMessageEntity> {
|
|
||||||
this.ensureInitialized()
|
|
||||||
|
|
||||||
const now = new Date().toISOString()
|
|
||||||
const insertData: InsertSessionMessageRow = {
|
|
||||||
session_id: sessionId,
|
|
||||||
role: 'user',
|
|
||||||
content: prompt,
|
|
||||||
agent_session_id: agentSessionId,
|
|
||||||
created_at: now,
|
|
||||||
updated_at: now
|
|
||||||
}
|
|
||||||
|
|
||||||
const [saved] = await tx.insert(sessionMessagesTable).values(insertData).returning()
|
|
||||||
|
|
||||||
return this.deserializeSessionMessage(saved) as AgentSessionMessageEntity
|
|
||||||
}
|
|
||||||
|
|
||||||
createSessionMessage(session: GetAgentSessionResponse, messageData: CreateSessionMessageRequest): EventEmitter {
|
createSessionMessage(session: GetAgentSessionResponse, messageData: CreateSessionMessageRequest): EventEmitter {
|
||||||
this.ensureInitialized()
|
this.ensureInitialized()
|
||||||
|
|
||||||
@ -210,12 +187,8 @@ export class SessionMessageService extends BaseService {
|
|||||||
req: CreateSessionMessageRequest,
|
req: CreateSessionMessageRequest,
|
||||||
sessionStream: EventEmitter
|
sessionStream: EventEmitter
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
const previousMessages = session.messages || []
|
const agentSessionId = await this.getLastAgentSessionId(session.id)
|
||||||
let agentSessionId: string = ''
|
let newAgentSessionId = ''
|
||||||
if (previousMessages.length > 0) {
|
|
||||||
agentSessionId = previousMessages[previousMessages.length - 1].agent_session_id
|
|
||||||
}
|
|
||||||
|
|
||||||
logger.debug('Session Message stream message data:', { message: req, session_id: agentSessionId })
|
logger.debug('Session Message stream message data:', { message: req, session_id: agentSessionId })
|
||||||
|
|
||||||
if (session.agent_type !== 'claude-code') {
|
if (session.agent_type !== 'claude-code') {
|
||||||
@ -223,7 +196,6 @@ export class SessionMessageService extends BaseService {
|
|||||||
logger.error('Unsupported agent type for streaming:', { agent_type: session.agent_type })
|
logger.error('Unsupported agent type for streaming:', { agent_type: session.agent_type })
|
||||||
throw new Error('Unsupported agent type for streaming')
|
throw new Error('Unsupported agent type for streaming')
|
||||||
}
|
}
|
||||||
let newAgentSessionId = ''
|
|
||||||
|
|
||||||
// Create the streaming agent invocation (using invokeStream for streaming)
|
// Create the streaming agent invocation (using invokeStream for streaming)
|
||||||
const claudeStream = this.cc.invoke(req.content, session.accessible_paths[0], agentSessionId, {
|
const claudeStream = this.cc.invoke(req.content, session.accessible_paths[0], agentSessionId, {
|
||||||
@ -261,30 +233,55 @@ export class SessionMessageService extends BaseService {
|
|||||||
|
|
||||||
sessionStream.emit('data', {
|
sessionStream.emit('data', {
|
||||||
type: 'error',
|
type: 'error',
|
||||||
error: serializeError(underlyingError)
|
error: serializeError(underlyingError),
|
||||||
|
persistScheduled: false
|
||||||
})
|
})
|
||||||
// Always emit a finish chunk at the end
|
// Always emit a finish chunk at the end
|
||||||
sessionStream.emit('data', {
|
sessionStream.emit('data', {
|
||||||
type: 'finish'
|
type: 'finish',
|
||||||
|
persistScheduled: false
|
||||||
})
|
})
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
case 'complete': {
|
case 'complete': {
|
||||||
// Then handle async persistence
|
const completionPayload = event.result ?? accumulator.toModelMessage('assistant')
|
||||||
this.database.transaction(async (tx) => {
|
|
||||||
await this.saveUserMessage(tx, session.id, req.content, newAgentSessionId)
|
|
||||||
await this.persistSessionMessageAsync({
|
|
||||||
tx,
|
|
||||||
session,
|
|
||||||
accumulator,
|
|
||||||
agentSessionId: newAgentSessionId
|
|
||||||
})
|
|
||||||
})
|
|
||||||
// Always emit a finish chunk at the end
|
|
||||||
sessionStream.emit('data', {
|
sessionStream.emit('data', {
|
||||||
type: 'finish'
|
type: 'complete',
|
||||||
|
result: completionPayload
|
||||||
})
|
})
|
||||||
|
|
||||||
|
try {
|
||||||
|
const persisted = await this.database.transaction(async (tx) => {
|
||||||
|
const userMessage = await this.persistUserMessage(tx, session.id, req.content, newAgentSessionId)
|
||||||
|
const assistantMessage = await this.persistAssistantMessage({
|
||||||
|
tx,
|
||||||
|
session,
|
||||||
|
accumulator,
|
||||||
|
agentSessionId: newAgentSessionId
|
||||||
|
})
|
||||||
|
|
||||||
|
return { userMessage, assistantMessage }
|
||||||
|
})
|
||||||
|
|
||||||
|
sessionStream.emit('data', {
|
||||||
|
type: 'persisted',
|
||||||
|
message: persisted.assistantMessage,
|
||||||
|
userMessage: persisted.userMessage
|
||||||
|
})
|
||||||
|
} catch (persistError) {
|
||||||
|
sessionStream.emit('data', {
|
||||||
|
type: 'persist-error',
|
||||||
|
error: serializeError(persistError)
|
||||||
|
})
|
||||||
|
} finally {
|
||||||
|
// Always emit a finish chunk at the end
|
||||||
|
sessionStream.emit('data', {
|
||||||
|
type: 'finish',
|
||||||
|
persistScheduled: true
|
||||||
|
})
|
||||||
|
}
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -304,7 +301,51 @@ export class SessionMessageService extends BaseService {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
private async persistSessionMessageAsync({
|
private async getLastAgentSessionId(sessionId: string): Promise<string> {
|
||||||
|
this.ensureInitialized()
|
||||||
|
|
||||||
|
try {
|
||||||
|
const result = await this.database
|
||||||
|
.select({ agent_session_id: sessionMessagesTable.agent_session_id })
|
||||||
|
.from(sessionMessagesTable)
|
||||||
|
.where(eq(sessionMessagesTable.session_id, sessionId))
|
||||||
|
.orderBy(desc(sessionMessagesTable.created_at))
|
||||||
|
.limit(1)
|
||||||
|
|
||||||
|
return result[0]?.agent_session_id || ''
|
||||||
|
} catch (error) {
|
||||||
|
logger.error('Failed to get last agent session ID', {
|
||||||
|
sessionId,
|
||||||
|
error
|
||||||
|
})
|
||||||
|
return ''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async persistUserMessage(
|
||||||
|
tx: any,
|
||||||
|
sessionId: string,
|
||||||
|
prompt: string,
|
||||||
|
agentSessionId: string
|
||||||
|
): Promise<AgentSessionMessageEntity> {
|
||||||
|
this.ensureInitialized()
|
||||||
|
|
||||||
|
const now = new Date().toISOString()
|
||||||
|
const insertData: InsertSessionMessageRow = {
|
||||||
|
session_id: sessionId,
|
||||||
|
role: 'user',
|
||||||
|
content: prompt,
|
||||||
|
agent_session_id: agentSessionId,
|
||||||
|
created_at: now,
|
||||||
|
updated_at: now
|
||||||
|
}
|
||||||
|
|
||||||
|
const [saved] = await tx.insert(sessionMessagesTable).values(insertData).returning()
|
||||||
|
|
||||||
|
return this.deserializeSessionMessage(saved) as AgentSessionMessageEntity
|
||||||
|
}
|
||||||
|
|
||||||
|
private async persistAssistantMessage({
|
||||||
tx,
|
tx,
|
||||||
session,
|
session,
|
||||||
accumulator,
|
accumulator,
|
||||||
@ -314,11 +355,11 @@ export class SessionMessageService extends BaseService {
|
|||||||
session: GetAgentSessionResponse
|
session: GetAgentSessionResponse
|
||||||
accumulator: ChunkAccumulator
|
accumulator: ChunkAccumulator
|
||||||
agentSessionId: string
|
agentSessionId: string
|
||||||
}) {
|
}): Promise<AgentSessionMessageEntity> {
|
||||||
if (!session?.id) {
|
if (!session?.id) {
|
||||||
const missingSessionError = new Error('Missing session_id for persisted message')
|
const missingSessionError = new Error('Missing session_id for persisted message')
|
||||||
logger.error('error persisting session message', { error: missingSessionError })
|
logger.error('error persisting session message', { error: missingSessionError })
|
||||||
return
|
throw missingSessionError
|
||||||
}
|
}
|
||||||
|
|
||||||
const sessionId = session.id
|
const sessionId = session.id
|
||||||
@ -340,10 +381,13 @@ export class SessionMessageService extends BaseService {
|
|||||||
updated_at: now
|
updated_at: now
|
||||||
}
|
}
|
||||||
|
|
||||||
await tx.insert(sessionMessagesTable).values(insertData).returning()
|
const [saved] = await tx.insert(sessionMessagesTable).values(insertData).returning()
|
||||||
logger.debug('Success Persisted session message')
|
logger.debug('Success Persisted session message')
|
||||||
|
|
||||||
|
return this.deserializeSessionMessage(saved) as AgentSessionMessageEntity
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error('Failed to persist session message', { error })
|
logger.error('Failed to persist session message', { error })
|
||||||
|
throw error
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
@host=http://localhost:23333
|
@host=http://localhost:23333
|
||||||
@token=cs-sk-af798ed4-7cf5-4fd7-ae4b-df203b164194
|
@token=cs-sk-af798ed4-7cf5-4fd7-ae4b-df203b164194
|
||||||
@agent_id=agent_1758092281575_tn9dxio9k
|
@agent_id=agent_1758092281575_tn9dxio9k
|
||||||
@session_id=session_1758092305477_b0g0cmnkp
|
@session_id=session_1758252305914_9kef8yven
|
||||||
|
|
||||||
### List Sessions
|
### List Sessions
|
||||||
GET {{host}}/v1/agents/{{agent_id}}/sessions
|
GET {{host}}/v1/agents/{{agent_id}}/sessions
|
||||||
@ -15,7 +15,14 @@ POST {{host}}/v1/agents/{{agent_id}}/sessions
|
|||||||
Authorization: Bearer {{token}}
|
Authorization: Bearer {{token}}
|
||||||
Content-Type: application/json
|
Content-Type: application/json
|
||||||
|
|
||||||
{}
|
{
|
||||||
|
"name": "Story Writing Session 1",
|
||||||
|
"instructions": "You are a creative writing assistant. Help me brainstorm and write engaging stories.",
|
||||||
|
"model": "anthropic:claude-sonnet-4",
|
||||||
|
"accessible_paths": [
|
||||||
|
"~/Documents/stories"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
### Get Session Details
|
### Get Session Details
|
||||||
GET {{host}}/v1/agents/{{agent_id}}/sessions/{{session_id}}
|
GET {{host}}/v1/agents/{{agent_id}}/sessions/{{session_id}}
|
||||||
@ -27,14 +34,28 @@ DELETE {{host}}/v1/agents/{{agent_id}}/sessions/{{session_id}}
|
|||||||
Authorization: Bearer {{token}}
|
Authorization: Bearer {{token}}
|
||||||
Content-Type: application/json
|
Content-Type: application/json
|
||||||
|
|
||||||
### Update Session
|
### Full Update Session
|
||||||
PUT {{host}}/v1/agents/{{agent_id}}/sessions/{{session_id}}
|
PUT {{host}}/v1/agents/{{agent_id}}/sessions/{{session_id}}
|
||||||
Authorization: Bearer {{token}}
|
Authorization: Bearer {{token}}
|
||||||
Content-Type: application/json
|
Content-Type: application/json
|
||||||
|
|
||||||
{
|
{
|
||||||
"name": "Code Review Session 1",
|
"name": "Story Writing Session 2",
|
||||||
"instructions": "Review the newly implemented feature for bugs and improvements"
|
"instructions": "You are a creative writing assistant. Help me brainstorm and write engaging stories.",
|
||||||
|
"model": "anthropic:claude-sonnet-4",
|
||||||
|
"accessible_paths": [
|
||||||
|
"~/Documents/stories"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
### Partial Update Session
|
||||||
|
PATCH {{host}}/v1/agents/{{agent_id}}/sessions/{{session_id}}
|
||||||
|
Authorization: Bearer {{token}}
|
||||||
|
Content-Type: application/json
|
||||||
|
|
||||||
|
{
|
||||||
|
"instructions": "You are a creative writing assistant. Help me brainstorm and write engaging stories. Focus on character development and plot structure.",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -44,5 +65,5 @@ Authorization: Bearer {{token}}
|
|||||||
Content-Type: application/json
|
Content-Type: application/json
|
||||||
|
|
||||||
{
|
{
|
||||||
"content": "a joke about programmers"
|
"content": "Write a short story about a robot learning to love."
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user