Files
Termix/plugins/ai/migrations/snapshot.json
T
ZacharyZcR bf817d8bd1 feat(ai): add remote coding agent sessions for SSH hosts (#1545)
* feat(ai): add host coding agent sessions with configured providers

* Wait for agent initialization and shutdown before resuming sessions

* Keep Pi transcripts outside its configuration migration directory

* Cover Pi session directory separation

* Update core permission catalog expectations for remote agents

* Install remote agent runtimes from verified official sources

* Wait for the identity panel credentials request in its test

* Add scoped SSH forwarding setup for remote agents

* Verify forwarding setup through a fresh SSH connection

* Bound the SSH forwarding verification timeout

* Return the forwarding verification callback result

* fix(ai): support agent send and interrupt keyboard shortcuts

* feat(ai): add agent queues attachments worktrees and session recovery

* fix(ai): handle deleted workspace paths and duplicate status events

* fix(ai): accept file references in root workspaces

* fix(ai): refresh paused queues after agent errors

* fix(ai): store agent sessions in plugin tables and lock down OpenCode

Agent sessions lived in a single ctx.kv value holding up to 2000 events,
which passed the 256 KB kv limit within minutes of a normal run. Every
save after that failed, so history, nativeId, queue and archive changes
were lost and every event wrote a kv audit row.

Sessions, events and queued prompts now have their own tables. A running
agent appends events in batches at most once a second with a lazy save;
session and queue changes save immediately. Prompts, drafts and stored
event text are capped in UTF-8 bytes to fit MySQL TEXT. kv:own is no
longer requested.

The OpenCode server now requires a per-session password, so other local
accounts on the host cannot drive the agent through its loopback port.

* test(upgrade): include agent session tables in the reviewed upgrade SQL
2026-10-03 16:01:47 -05:00

369 lines
7.7 KiB
JSON

{
"version": 1,
"tables": {
"providers": {
"columns": {
"id": {
"type": "id",
"primaryKey": true,
"notNull": true
},
"syncId": {
"type": "varchar",
"length": 255,
"unique": true
},
"userId": {
"type": "refUser",
"length": 255,
"notNull": true
},
"providerType": {
"type": "text",
"notNull": true
},
"label": {
"type": "varchar",
"length": 255,
"notNull": true
},
"baseUrl": {
"type": "text"
},
"apiKeyPrefix": {
"type": "text"
},
"defaultModel": {
"type": "text"
},
"enabled": {
"type": "boolean",
"notNull": true,
"defaultValue": true
},
"createdAt": {
"type": "timestamp",
"notNull": true,
"defaultNow": true
},
"updatedAt": {
"type": "timestamp",
"notNull": true,
"defaultNow": true
}
},
"indexes": [
{
"name": "idx_ai_providers_user_label",
"columns": ["userId", "label"],
"unique": true
}
],
"adopts": "ai_providers"
},
"conversations": {
"columns": {
"id": {
"type": "id",
"primaryKey": true,
"notNull": true
},
"userId": {
"type": "refUser",
"length": 255,
"notNull": true
},
"title": {
"type": "text"
},
"providerId": {
"type": "integer"
},
"model": {
"type": "text"
},
"createdAt": {
"type": "timestamp",
"notNull": true,
"defaultNow": true
},
"updatedAt": {
"type": "timestamp",
"notNull": true,
"defaultNow": true
}
},
"indexes": [
{
"name": "idx_ai_conversations_user",
"columns": ["userId", "updatedAt"]
}
],
"adopts": "ai_conversations"
},
"messages": {
"columns": {
"id": {
"type": "id",
"primaryKey": true,
"notNull": true
},
"conversationId": {
"type": "integer",
"notNull": true
},
"role": {
"type": "text",
"notNull": true
},
"content": {
"type": "text",
"notNull": true,
"defaultValue": ""
},
"toolCalls": {
"type": "text"
},
"createdAt": {
"type": "timestamp",
"notNull": true,
"defaultNow": true
}
},
"indexes": [
{
"name": "idx_ai_messages_conversation",
"columns": ["conversationId", "createdAt"]
}
],
"adopts": "ai_messages"
},
"proposals": {
"columns": {
"id": {
"type": "id",
"primaryKey": true,
"notNull": true
},
"conversationId": {
"type": "integer",
"notNull": true
},
"userId": {
"type": "refUser",
"length": 255,
"notNull": true
},
"kind": {
"type": "varchar",
"length": 255,
"notNull": true
},
"summary": {
"type": "text"
},
"payload": {
"type": "text",
"notNull": true,
"defaultValue": "{}"
},
"status": {
"type": "varchar",
"length": 32,
"notNull": true,
"defaultValue": "pending"
},
"appliedAt": {
"type": "text"
},
"resultSummary": {
"type": "text"
},
"createdAt": {
"type": "timestamp",
"notNull": true,
"defaultNow": true
}
},
"indexes": [
{
"name": "idx_ai_proposals_user",
"columns": ["userId", "status"]
},
{
"name": "idx_ai_proposals_conversation",
"columns": ["conversationId"]
}
],
"adopts": "ai_proposals"
},
"agent_sessions": {
"columns": {
"id": {
"type": "id",
"primaryKey": true,
"notNull": true
},
"sessionId": {
"type": "varchar",
"length": 36,
"notNull": true,
"unique": true
},
"userId": {
"type": "refUser",
"length": 255,
"notNull": true
},
"hostId": {
"type": "integer",
"notNull": true
},
"providerId": {
"type": "integer",
"notNull": true
},
"agent": {
"type": "varchar",
"length": 32,
"notNull": true
},
"model": {
"type": "text",
"notNull": true
},
"cwd": {
"type": "text",
"notNull": true
},
"executable": {
"type": "text",
"notNull": true
},
"nativeId": {
"type": "text"
},
"title": {
"type": "text"
},
"archived": {
"type": "boolean",
"notNull": true,
"defaultValue": false
},
"queuePaused": {
"type": "boolean",
"notNull": true,
"defaultValue": false
},
"draft": {
"type": "text"
},
"attachments": {
"type": "text",
"notNull": true,
"defaultValue": "[]"
},
"updatedAt": {
"type": "text",
"notNull": true
}
},
"indexes": [
{
"name": "idx_ai_agent_sessions_user",
"columns": ["userId"]
}
]
},
"agent_events": {
"columns": {
"id": {
"type": "id",
"primaryKey": true,
"notNull": true
},
"sessionId": {
"type": "varchar",
"length": 36,
"notNull": true
},
"userId": {
"type": "refUser",
"length": 255,
"notNull": true
},
"seq": {
"type": "integer",
"notNull": true
},
"kind": {
"type": "varchar",
"length": 16,
"notNull": true
},
"text": {
"type": "text",
"notNull": true
},
"requestId": {
"type": "text"
},
"choices": {
"type": "text"
}
},
"indexes": [
{
"name": "idx_ai_agent_events_session_seq",
"columns": ["sessionId", "seq"],
"unique": true
}
]
},
"agent_queue": {
"columns": {
"id": {
"type": "id",
"primaryKey": true,
"notNull": true
},
"sessionId": {
"type": "varchar",
"length": 36,
"notNull": true
},
"userId": {
"type": "refUser",
"length": 255,
"notNull": true
},
"promptId": {
"type": "varchar",
"length": 36,
"notNull": true
},
"position": {
"type": "integer",
"notNull": true
},
"text": {
"type": "text",
"notNull": true
},
"attachmentIds": {
"type": "text",
"notNull": true,
"defaultValue": "[]"
}
},
"indexes": [
{
"name": "idx_ai_agent_queue_session",
"columns": ["sessionId", "position"]
}
]
}
}
}