summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorShoubhit Dash <[email protected]>2026-03-13 15:48:43 +0530
committerGitHub <[email protected]>2026-03-13 15:48:43 +0530
commit9457493696b3b7136c743e6de9e50977ae1e6f8c (patch)
tree0e44f9498dfd6ee9847736823b2ee2fada90baff
parentff748b82ca55a20aca6881ea72742afec94450ab (diff)
downloadopencode-9457493696b3b7136c743e6de9e50977ae1e6f8c.tar.gz
opencode-9457493696b3b7136c743e6de9e50977ae1e6f8c.zip
perf(server): paginate session history (#17134)
-rw-r--r--packages/opencode/migration/20260312043431_session_message_cursor/migration.sql4
-rw-r--r--packages/opencode/migration/20260312043431_session_message_cursor/snapshot.json1226
-rw-r--r--packages/opencode/src/server/routes/session.ts60
-rw-r--r--packages/opencode/src/session/message-v2.ts160
-rw-r--r--packages/opencode/src/session/session.sql.ts7
-rw-r--r--packages/opencode/test/server/session-messages.test.ts119
-rw-r--r--packages/opencode/test/session/messages-pagination.test.ts115
-rw-r--r--packages/sdk/js/src/v2/gen/sdk.gen.ts2
-rw-r--r--packages/sdk/js/src/v2/gen/types.gen.ts4
-rw-r--r--packages/sdk/openapi.json1708
10 files changed, 3042 insertions, 363 deletions
diff --git a/packages/opencode/migration/20260312043431_session_message_cursor/migration.sql b/packages/opencode/migration/20260312043431_session_message_cursor/migration.sql
new file mode 100644
index 000000000..e2bd08137
--- /dev/null
+++ b/packages/opencode/migration/20260312043431_session_message_cursor/migration.sql
@@ -0,0 +1,4 @@
+DROP INDEX IF EXISTS `message_session_idx`;--> statement-breakpoint
+DROP INDEX IF EXISTS `part_message_idx`;--> statement-breakpoint
+CREATE INDEX `message_session_time_created_id_idx` ON `message` (`session_id`,`time_created`,`id`);--> statement-breakpoint
+CREATE INDEX `part_message_id_id_idx` ON `part` (`message_id`,`id`); \ No newline at end of file
diff --git a/packages/opencode/migration/20260312043431_session_message_cursor/snapshot.json b/packages/opencode/migration/20260312043431_session_message_cursor/snapshot.json
new file mode 100644
index 000000000..3e067163d
--- /dev/null
+++ b/packages/opencode/migration/20260312043431_session_message_cursor/snapshot.json
@@ -0,0 +1,1226 @@
+{
+ "version": "7",
+ "dialect": "sqlite",
+ "id": "37e1554d-af4c-43f2-aa7c-307fb49a315e",
+ "prevIds": [
+ "fb311f30-9948-4131-b15c-7d308478a878"
+ ],
+ "ddl": [
+ {
+ "name": "account_state",
+ "entityType": "tables"
+ },
+ {
+ "name": "account",
+ "entityType": "tables"
+ },
+ {
+ "name": "control_account",
+ "entityType": "tables"
+ },
+ {
+ "name": "workspace",
+ "entityType": "tables"
+ },
+ {
+ "name": "project",
+ "entityType": "tables"
+ },
+ {
+ "name": "message",
+ "entityType": "tables"
+ },
+ {
+ "name": "part",
+ "entityType": "tables"
+ },
+ {
+ "name": "permission",
+ "entityType": "tables"
+ },
+ {
+ "name": "session",
+ "entityType": "tables"
+ },
+ {
+ "name": "todo",
+ "entityType": "tables"
+ },
+ {
+ "name": "session_share",
+ "entityType": "tables"
+ },
+ {
+ "type": "integer",
+ "notNull": false,
+ "autoincrement": false,
+ "default": null,
+ "generated": null,
+ "name": "id",
+ "entityType": "columns",
+ "table": "account_state"
+ },
+ {
+ "type": "text",
+ "notNull": false,
+ "autoincrement": false,
+ "default": null,
+ "generated": null,
+ "name": "active_account_id",
+ "entityType": "columns",
+ "table": "account_state"
+ },
+ {
+ "type": "text",
+ "notNull": false,
+ "autoincrement": false,
+ "default": null,
+ "generated": null,
+ "name": "active_org_id",
+ "entityType": "columns",
+ "table": "account_state"
+ },
+ {
+ "type": "text",
+ "notNull": false,
+ "autoincrement": false,
+ "default": null,
+ "generated": null,
+ "name": "id",
+ "entityType": "columns",
+ "table": "account"
+ },
+ {
+ "type": "text",
+ "notNull": true,
+ "autoincrement": false,
+ "default": null,
+ "generated": null,
+ "name": "email",
+ "entityType": "columns",
+ "table": "account"
+ },
+ {
+ "type": "text",
+ "notNull": true,
+ "autoincrement": false,
+ "default": null,
+ "generated": null,
+ "name": "url",
+ "entityType": "columns",
+ "table": "account"
+ },
+ {
+ "type": "text",
+ "notNull": true,
+ "autoincrement": false,
+ "default": null,
+ "generated": null,
+ "name": "access_token",
+ "entityType": "columns",
+ "table": "account"
+ },
+ {
+ "type": "text",
+ "notNull": true,
+ "autoincrement": false,
+ "default": null,
+ "generated": null,
+ "name": "refresh_token",
+ "entityType": "columns",
+ "table": "account"
+ },
+ {
+ "type": "integer",
+ "notNull": false,
+ "autoincrement": false,
+ "default": null,
+ "generated": null,
+ "name": "token_expiry",
+ "entityType": "columns",
+ "table": "account"
+ },
+ {
+ "type": "integer",
+ "notNull": true,
+ "autoincrement": false,
+ "default": null,
+ "generated": null,
+ "name": "time_created",
+ "entityType": "columns",
+ "table": "account"
+ },
+ {
+ "type": "integer",
+ "notNull": true,
+ "autoincrement": false,
+ "default": null,
+ "generated": null,
+ "name": "time_updated",
+ "entityType": "columns",
+ "table": "account"
+ },
+ {
+ "type": "text",
+ "notNull": true,
+ "autoincrement": false,
+ "default": null,
+ "generated": null,
+ "name": "email",
+ "entityType": "columns",
+ "table": "control_account"
+ },
+ {
+ "type": "text",
+ "notNull": true,
+ "autoincrement": false,
+ "default": null,
+ "generated": null,
+ "name": "url",
+ "entityType": "columns",
+ "table": "control_account"
+ },
+ {
+ "type": "text",
+ "notNull": true,
+ "autoincrement": false,
+ "default": null,
+ "generated": null,
+ "name": "access_token",
+ "entityType": "columns",
+ "table": "control_account"
+ },
+ {
+ "type": "text",
+ "notNull": true,
+ "autoincrement": false,
+ "default": null,
+ "generated": null,
+ "name": "refresh_token",
+ "entityType": "columns",
+ "table": "control_account"
+ },
+ {
+ "type": "integer",
+ "notNull": false,
+ "autoincrement": false,
+ "default": null,
+ "generated": null,
+ "name": "token_expiry",
+ "entityType": "columns",
+ "table": "control_account"
+ },
+ {
+ "type": "integer",
+ "notNull": true,
+ "autoincrement": false,
+ "default": null,
+ "generated": null,
+ "name": "active",
+ "entityType": "columns",
+ "table": "control_account"
+ },
+ {
+ "type": "integer",
+ "notNull": true,
+ "autoincrement": false,
+ "default": null,
+ "generated": null,
+ "name": "time_created",
+ "entityType": "columns",
+ "table": "control_account"
+ },
+ {
+ "type": "integer",
+ "notNull": true,
+ "autoincrement": false,
+ "default": null,
+ "generated": null,
+ "name": "time_updated",
+ "entityType": "columns",
+ "table": "control_account"
+ },
+ {
+ "type": "text",
+ "notNull": false,
+ "autoincrement": false,
+ "default": null,
+ "generated": null,
+ "name": "id",
+ "entityType": "columns",
+ "table": "workspace"
+ },
+ {
+ "type": "text",
+ "notNull": true,
+ "autoincrement": false,
+ "default": null,
+ "generated": null,
+ "name": "type",
+ "entityType": "columns",
+ "table": "workspace"
+ },
+ {
+ "type": "text",
+ "notNull": false,
+ "autoincrement": false,
+ "default": null,
+ "generated": null,
+ "name": "branch",
+ "entityType": "columns",
+ "table": "workspace"
+ },
+ {
+ "type": "text",
+ "notNull": false,
+ "autoincrement": false,
+ "default": null,
+ "generated": null,
+ "name": "name",
+ "entityType": "columns",
+ "table": "workspace"
+ },
+ {
+ "type": "text",
+ "notNull": false,
+ "autoincrement": false,
+ "default": null,
+ "generated": null,
+ "name": "directory",
+ "entityType": "columns",
+ "table": "workspace"
+ },
+ {
+ "type": "text",
+ "notNull": false,
+ "autoincrement": false,
+ "default": null,
+ "generated": null,
+ "name": "extra",
+ "entityType": "columns",
+ "table": "workspace"
+ },
+ {
+ "type": "text",
+ "notNull": true,
+ "autoincrement": false,
+ "default": null,
+ "generated": null,
+ "name": "project_id",
+ "entityType": "columns",
+ "table": "workspace"
+ },
+ {
+ "type": "text",
+ "notNull": false,
+ "autoincrement": false,
+ "default": null,
+ "generated": null,
+ "name": "id",
+ "entityType": "columns",
+ "table": "project"
+ },
+ {
+ "type": "text",
+ "notNull": true,
+ "autoincrement": false,
+ "default": null,
+ "generated": null,
+ "name": "worktree",
+ "entityType": "columns",
+ "table": "project"
+ },
+ {
+ "type": "text",
+ "notNull": false,
+ "autoincrement": false,
+ "default": null,
+ "generated": null,
+ "name": "vcs",
+ "entityType": "columns",
+ "table": "project"
+ },
+ {
+ "type": "text",
+ "notNull": false,
+ "autoincrement": false,
+ "default": null,
+ "generated": null,
+ "name": "name",
+ "entityType": "columns",
+ "table": "project"
+ },
+ {
+ "type": "text",
+ "notNull": false,
+ "autoincrement": false,
+ "default": null,
+ "generated": null,
+ "name": "icon_url",
+ "entityType": "columns",
+ "table": "project"
+ },
+ {
+ "type": "text",
+ "notNull": false,
+ "autoincrement": false,
+ "default": null,
+ "generated": null,
+ "name": "icon_color",
+ "entityType": "columns",
+ "table": "project"
+ },
+ {
+ "type": "integer",
+ "notNull": true,
+ "autoincrement": false,
+ "default": null,
+ "generated": null,
+ "name": "time_created",
+ "entityType": "columns",
+ "table": "project"
+ },
+ {
+ "type": "integer",
+ "notNull": true,
+ "autoincrement": false,
+ "default": null,
+ "generated": null,
+ "name": "time_updated",
+ "entityType": "columns",
+ "table": "project"
+ },
+ {
+ "type": "integer",
+ "notNull": false,
+ "autoincrement": false,
+ "default": null,
+ "generated": null,
+ "name": "time_initialized",
+ "entityType": "columns",
+ "table": "project"
+ },
+ {
+ "type": "text",
+ "notNull": true,
+ "autoincrement": false,
+ "default": null,
+ "generated": null,
+ "name": "sandboxes",
+ "entityType": "columns",
+ "table": "project"
+ },
+ {
+ "type": "text",
+ "notNull": false,
+ "autoincrement": false,
+ "default": null,
+ "generated": null,
+ "name": "commands",
+ "entityType": "columns",
+ "table": "project"
+ },
+ {
+ "type": "text",
+ "notNull": false,
+ "autoincrement": false,
+ "default": null,
+ "generated": null,
+ "name": "id",
+ "entityType": "columns",
+ "table": "message"
+ },
+ {
+ "type": "text",
+ "notNull": true,
+ "autoincrement": false,
+ "default": null,
+ "generated": null,
+ "name": "session_id",
+ "entityType": "columns",
+ "table": "message"
+ },
+ {
+ "type": "integer",
+ "notNull": true,
+ "autoincrement": false,
+ "default": null,
+ "generated": null,
+ "name": "time_created",
+ "entityType": "columns",
+ "table": "message"
+ },
+ {
+ "type": "integer",
+ "notNull": true,
+ "autoincrement": false,
+ "default": null,
+ "generated": null,
+ "name": "time_updated",
+ "entityType": "columns",
+ "table": "message"
+ },
+ {
+ "type": "text",
+ "notNull": true,
+ "autoincrement": false,
+ "default": null,
+ "generated": null,
+ "name": "data",
+ "entityType": "columns",
+ "table": "message"
+ },
+ {
+ "type": "text",
+ "notNull": false,
+ "autoincrement": false,
+ "default": null,
+ "generated": null,
+ "name": "id",
+ "entityType": "columns",
+ "table": "part"
+ },
+ {
+ "type": "text",
+ "notNull": true,
+ "autoincrement": false,
+ "default": null,
+ "generated": null,
+ "name": "message_id",
+ "entityType": "columns",
+ "table": "part"
+ },
+ {
+ "type": "text",
+ "notNull": true,
+ "autoincrement": false,
+ "default": null,
+ "generated": null,
+ "name": "session_id",
+ "entityType": "columns",
+ "table": "part"
+ },
+ {
+ "type": "integer",
+ "notNull": true,
+ "autoincrement": false,
+ "default": null,
+ "generated": null,
+ "name": "time_created",
+ "entityType": "columns",
+ "table": "part"
+ },
+ {
+ "type": "integer",
+ "notNull": true,
+ "autoincrement": false,
+ "default": null,
+ "generated": null,
+ "name": "time_updated",
+ "entityType": "columns",
+ "table": "part"
+ },
+ {
+ "type": "text",
+ "notNull": true,
+ "autoincrement": false,
+ "default": null,
+ "generated": null,
+ "name": "data",
+ "entityType": "columns",
+ "table": "part"
+ },
+ {
+ "type": "text",
+ "notNull": false,
+ "autoincrement": false,
+ "default": null,
+ "generated": null,
+ "name": "project_id",
+ "entityType": "columns",
+ "table": "permission"
+ },
+ {
+ "type": "integer",
+ "notNull": true,
+ "autoincrement": false,
+ "default": null,
+ "generated": null,
+ "name": "time_created",
+ "entityType": "columns",
+ "table": "permission"
+ },
+ {
+ "type": "integer",
+ "notNull": true,
+ "autoincrement": false,
+ "default": null,
+ "generated": null,
+ "name": "time_updated",
+ "entityType": "columns",
+ "table": "permission"
+ },
+ {
+ "type": "text",
+ "notNull": true,
+ "autoincrement": false,
+ "default": null,
+ "generated": null,
+ "name": "data",
+ "entityType": "columns",
+ "table": "permission"
+ },
+ {
+ "type": "text",
+ "notNull": false,
+ "autoincrement": false,
+ "default": null,
+ "generated": null,
+ "name": "id",
+ "entityType": "columns",
+ "table": "session"
+ },
+ {
+ "type": "text",
+ "notNull": true,
+ "autoincrement": false,
+ "default": null,
+ "generated": null,
+ "name": "project_id",
+ "entityType": "columns",
+ "table": "session"
+ },
+ {
+ "type": "text",
+ "notNull": false,
+ "autoincrement": false,
+ "default": null,
+ "generated": null,
+ "name": "workspace_id",
+ "entityType": "columns",
+ "table": "session"
+ },
+ {
+ "type": "text",
+ "notNull": false,
+ "autoincrement": false,
+ "default": null,
+ "generated": null,
+ "name": "parent_id",
+ "entityType": "columns",
+ "table": "session"
+ },
+ {
+ "type": "text",
+ "notNull": true,
+ "autoincrement": false,
+ "default": null,
+ "generated": null,
+ "name": "slug",
+ "entityType": "columns",
+ "table": "session"
+ },
+ {
+ "type": "text",
+ "notNull": true,
+ "autoincrement": false,
+ "default": null,
+ "generated": null,
+ "name": "directory",
+ "entityType": "columns",
+ "table": "session"
+ },
+ {
+ "type": "text",
+ "notNull": true,
+ "autoincrement": false,
+ "default": null,
+ "generated": null,
+ "name": "title",
+ "entityType": "columns",
+ "table": "session"
+ },
+ {
+ "type": "text",
+ "notNull": true,
+ "autoincrement": false,
+ "default": null,
+ "generated": null,
+ "name": "version",
+ "entityType": "columns",
+ "table": "session"
+ },
+ {
+ "type": "text",
+ "notNull": false,
+ "autoincrement": false,
+ "default": null,
+ "generated": null,
+ "name": "share_url",
+ "entityType": "columns",
+ "table": "session"
+ },
+ {
+ "type": "integer",
+ "notNull": false,
+ "autoincrement": false,
+ "default": null,
+ "generated": null,
+ "name": "summary_additions",
+ "entityType": "columns",
+ "table": "session"
+ },
+ {
+ "type": "integer",
+ "notNull": false,
+ "autoincrement": false,
+ "default": null,
+ "generated": null,
+ "name": "summary_deletions",
+ "entityType": "columns",
+ "table": "session"
+ },
+ {
+ "type": "integer",
+ "notNull": false,
+ "autoincrement": false,
+ "default": null,
+ "generated": null,
+ "name": "summary_files",
+ "entityType": "columns",
+ "table": "session"
+ },
+ {
+ "type": "text",
+ "notNull": false,
+ "autoincrement": false,
+ "default": null,
+ "generated": null,
+ "name": "summary_diffs",
+ "entityType": "columns",
+ "table": "session"
+ },
+ {
+ "type": "text",
+ "notNull": false,
+ "autoincrement": false,
+ "default": null,
+ "generated": null,
+ "name": "revert",
+ "entityType": "columns",
+ "table": "session"
+ },
+ {
+ "type": "text",
+ "notNull": false,
+ "autoincrement": false,
+ "default": null,
+ "generated": null,
+ "name": "permission",
+ "entityType": "columns",
+ "table": "session"
+ },
+ {
+ "type": "integer",
+ "notNull": true,
+ "autoincrement": false,
+ "default": null,
+ "generated": null,
+ "name": "time_created",
+ "entityType": "columns",
+ "table": "session"
+ },
+ {
+ "type": "integer",
+ "notNull": true,
+ "autoincrement": false,
+ "default": null,
+ "generated": null,
+ "name": "time_updated",
+ "entityType": "columns",
+ "table": "session"
+ },
+ {
+ "type": "integer",
+ "notNull": false,
+ "autoincrement": false,
+ "default": null,
+ "generated": null,
+ "name": "time_compacting",
+ "entityType": "columns",
+ "table": "session"
+ },
+ {
+ "type": "integer",
+ "notNull": false,
+ "autoincrement": false,
+ "default": null,
+ "generated": null,
+ "name": "time_archived",
+ "entityType": "columns",
+ "table": "session"
+ },
+ {
+ "type": "text",
+ "notNull": true,
+ "autoincrement": false,
+ "default": null,
+ "generated": null,
+ "name": "session_id",
+ "entityType": "columns",
+ "table": "todo"
+ },
+ {
+ "type": "text",
+ "notNull": true,
+ "autoincrement": false,
+ "default": null,
+ "generated": null,
+ "name": "content",
+ "entityType": "columns",
+ "table": "todo"
+ },
+ {
+ "type": "text",
+ "notNull": true,
+ "autoincrement": false,
+ "default": null,
+ "generated": null,
+ "name": "status",
+ "entityType": "columns",
+ "table": "todo"
+ },
+ {
+ "type": "text",
+ "notNull": true,
+ "autoincrement": false,
+ "default": null,
+ "generated": null,
+ "name": "priority",
+ "entityType": "columns",
+ "table": "todo"
+ },
+ {
+ "type": "integer",
+ "notNull": true,
+ "autoincrement": false,
+ "default": null,
+ "generated": null,
+ "name": "position",
+ "entityType": "columns",
+ "table": "todo"
+ },
+ {
+ "type": "integer",
+ "notNull": true,
+ "autoincrement": false,
+ "default": null,
+ "generated": null,
+ "name": "time_created",
+ "entityType": "columns",
+ "table": "todo"
+ },
+ {
+ "type": "integer",
+ "notNull": true,
+ "autoincrement": false,
+ "default": null,
+ "generated": null,
+ "name": "time_updated",
+ "entityType": "columns",
+ "table": "todo"
+ },
+ {
+ "type": "text",
+ "notNull": false,
+ "autoincrement": false,
+ "default": null,
+ "generated": null,
+ "name": "session_id",
+ "entityType": "columns",
+ "table": "session_share"
+ },
+ {
+ "type": "text",
+ "notNull": true,
+ "autoincrement": false,
+ "default": null,
+ "generated": null,
+ "name": "id",
+ "entityType": "columns",
+ "table": "session_share"
+ },
+ {
+ "type": "text",
+ "notNull": true,
+ "autoincrement": false,
+ "default": null,
+ "generated": null,
+ "name": "secret",
+ "entityType": "columns",
+ "table": "session_share"
+ },
+ {
+ "type": "text",
+ "notNull": true,
+ "autoincrement": false,
+ "default": null,
+ "generated": null,
+ "name": "url",
+ "entityType": "columns",
+ "table": "session_share"
+ },
+ {
+ "type": "integer",
+ "notNull": true,
+ "autoincrement": false,
+ "default": null,
+ "generated": null,
+ "name": "time_created",
+ "entityType": "columns",
+ "table": "session_share"
+ },
+ {
+ "type": "integer",
+ "notNull": true,
+ "autoincrement": false,
+ "default": null,
+ "generated": null,
+ "name": "time_updated",
+ "entityType": "columns",
+ "table": "session_share"
+ },
+ {
+ "columns": [
+ "active_account_id"
+ ],
+ "tableTo": "account",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "NO ACTION",
+ "onDelete": "SET NULL",
+ "nameExplicit": false,
+ "name": "fk_account_state_active_account_id_account_id_fk",
+ "entityType": "fks",
+ "table": "account_state"
+ },
+ {
+ "columns": [
+ "project_id"
+ ],
+ "tableTo": "project",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "NO ACTION",
+ "onDelete": "CASCADE",
+ "nameExplicit": false,
+ "name": "fk_workspace_project_id_project_id_fk",
+ "entityType": "fks",
+ "table": "workspace"
+ },
+ {
+ "columns": [
+ "session_id"
+ ],
+ "tableTo": "session",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "NO ACTION",
+ "onDelete": "CASCADE",
+ "nameExplicit": false,
+ "name": "fk_message_session_id_session_id_fk",
+ "entityType": "fks",
+ "table": "message"
+ },
+ {
+ "columns": [
+ "message_id"
+ ],
+ "tableTo": "message",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "NO ACTION",
+ "onDelete": "CASCADE",
+ "nameExplicit": false,
+ "name": "fk_part_message_id_message_id_fk",
+ "entityType": "fks",
+ "table": "part"
+ },
+ {
+ "columns": [
+ "project_id"
+ ],
+ "tableTo": "project",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "NO ACTION",
+ "onDelete": "CASCADE",
+ "nameExplicit": false,
+ "name": "fk_permission_project_id_project_id_fk",
+ "entityType": "fks",
+ "table": "permission"
+ },
+ {
+ "columns": [
+ "project_id"
+ ],
+ "tableTo": "project",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "NO ACTION",
+ "onDelete": "CASCADE",
+ "nameExplicit": false,
+ "name": "fk_session_project_id_project_id_fk",
+ "entityType": "fks",
+ "table": "session"
+ },
+ {
+ "columns": [
+ "session_id"
+ ],
+ "tableTo": "session",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "NO ACTION",
+ "onDelete": "CASCADE",
+ "nameExplicit": false,
+ "name": "fk_todo_session_id_session_id_fk",
+ "entityType": "fks",
+ "table": "todo"
+ },
+ {
+ "columns": [
+ "session_id"
+ ],
+ "tableTo": "session",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "NO ACTION",
+ "onDelete": "CASCADE",
+ "nameExplicit": false,
+ "name": "fk_session_share_session_id_session_id_fk",
+ "entityType": "fks",
+ "table": "session_share"
+ },
+ {
+ "columns": [
+ "email",
+ "url"
+ ],
+ "nameExplicit": false,
+ "name": "control_account_pk",
+ "entityType": "pks",
+ "table": "control_account"
+ },
+ {
+ "columns": [
+ "session_id",
+ "position"
+ ],
+ "nameExplicit": false,
+ "name": "todo_pk",
+ "entityType": "pks",
+ "table": "todo"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "account_state_pk",
+ "table": "account_state",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "account_pk",
+ "table": "account",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "workspace_pk",
+ "table": "workspace",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "project_pk",
+ "table": "project",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "message_pk",
+ "table": "message",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "part_pk",
+ "table": "part",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "project_id"
+ ],
+ "nameExplicit": false,
+ "name": "permission_pk",
+ "table": "permission",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "session_pk",
+ "table": "session",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "session_id"
+ ],
+ "nameExplicit": false,
+ "name": "session_share_pk",
+ "table": "session_share",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ {
+ "value": "session_id",
+ "isExpression": false
+ },
+ {
+ "value": "time_created",
+ "isExpression": false
+ },
+ {
+ "value": "id",
+ "isExpression": false
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "origin": "manual",
+ "name": "message_session_time_created_id_idx",
+ "entityType": "indexes",
+ "table": "message"
+ },
+ {
+ "columns": [
+ {
+ "value": "message_id",
+ "isExpression": false
+ },
+ {
+ "value": "id",
+ "isExpression": false
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "origin": "manual",
+ "name": "part_message_id_id_idx",
+ "entityType": "indexes",
+ "table": "part"
+ },
+ {
+ "columns": [
+ {
+ "value": "session_id",
+ "isExpression": false
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "origin": "manual",
+ "name": "part_session_idx",
+ "entityType": "indexes",
+ "table": "part"
+ },
+ {
+ "columns": [
+ {
+ "value": "project_id",
+ "isExpression": false
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "origin": "manual",
+ "name": "session_project_idx",
+ "entityType": "indexes",
+ "table": "session"
+ },
+ {
+ "columns": [
+ {
+ "value": "workspace_id",
+ "isExpression": false
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "origin": "manual",
+ "name": "session_workspace_idx",
+ "entityType": "indexes",
+ "table": "session"
+ },
+ {
+ "columns": [
+ {
+ "value": "parent_id",
+ "isExpression": false
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "origin": "manual",
+ "name": "session_parent_idx",
+ "entityType": "indexes",
+ "table": "session"
+ },
+ {
+ "columns": [
+ {
+ "value": "session_id",
+ "isExpression": false
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "origin": "manual",
+ "name": "todo_session_idx",
+ "entityType": "indexes",
+ "table": "todo"
+ }
+ ],
+ "renames": []
+} \ No newline at end of file
diff --git a/packages/opencode/src/server/routes/session.ts b/packages/opencode/src/server/routes/session.ts
index f74237374..b8fafd336 100644
--- a/packages/opencode/src/server/routes/session.ts
+++ b/packages/opencode/src/server/routes/session.ts
@@ -569,17 +569,65 @@ export const SessionRoutes = lazy(() =>
),
validator(
"query",
- z.object({
- limit: z.coerce.number().optional(),
- }),
+ z
+ .object({
+ limit: z.coerce
+ .number()
+ .int()
+ .min(0)
+ .optional()
+ .meta({ description: "Maximum number of messages to return" }),
+ before: z
+ .string()
+ .optional()
+ .meta({ description: "Opaque cursor for loading older messages" })
+ .refine(
+ (value) => {
+ if (!value) return true
+ try {
+ MessageV2.cursor.decode(value)
+ return true
+ } catch {
+ return false
+ }
+ },
+ { message: "Invalid cursor" },
+ ),
+ })
+ .refine((value) => !value.before || value.limit !== undefined, {
+ message: "before requires limit",
+ path: ["before"],
+ }),
),
async (c) => {
const query = c.req.valid("query")
- const messages = await Session.messages({
- sessionID: c.req.valid("param").sessionID,
+ const sessionID = c.req.valid("param").sessionID
+ if (query.limit === undefined) {
+ await Session.get(sessionID)
+ const messages = await Session.messages({ sessionID })
+ return c.json(messages)
+ }
+
+ if (query.limit === 0) {
+ await Session.get(sessionID)
+ const messages = await Session.messages({ sessionID })
+ return c.json(messages)
+ }
+
+ const page = await MessageV2.page({
+ sessionID,
limit: query.limit,
+ before: query.before,
})
- return c.json(messages)
+ if (page.cursor) {
+ const url = new URL(c.req.url)
+ url.searchParams.set("limit", query.limit.toString())
+ url.searchParams.set("before", page.cursor)
+ c.header("Access-Control-Expose-Headers", "Link, X-Next-Cursor")
+ c.header("Link", `<${url.toString()}>; rel=\"next\"`)
+ c.header("X-Next-Cursor", page.cursor)
+ }
+ return c.json(page.items)
},
)
.get(
diff --git a/packages/opencode/src/session/message-v2.ts b/packages/opencode/src/session/message-v2.ts
index 03ccb44c1..8e4babd61 100644
--- a/packages/opencode/src/session/message-v2.ts
+++ b/packages/opencode/src/session/message-v2.ts
@@ -6,8 +6,8 @@ import { APICallError, convertToModelMessages, LoadAPIKeyError, type ModelMessag
import { LSP } from "../lsp"
import { Snapshot } from "@/snapshot"
import { fn } from "@/util/fn"
-import { Database, eq, desc, inArray } from "@/storage/db"
-import { MessageTable, PartTable } from "./session.sql"
+import { Database, NotFoundError, and, desc, eq, inArray, lt, or } from "@/storage/db"
+import { MessageTable, PartTable, SessionTable } from "./session.sql"
import { ProviderTransform } from "@/provider/transform"
import { STATUS_CODES } from "http"
import { Storage } from "@/storage/storage"
@@ -494,6 +494,68 @@ export namespace MessageV2 {
})
export type WithParts = z.infer<typeof WithParts>
+ const Cursor = z.object({
+ id: MessageID.zod,
+ time: z.number(),
+ })
+ type Cursor = z.infer<typeof Cursor>
+
+ export const cursor = {
+ encode(input: Cursor) {
+ return Buffer.from(JSON.stringify(input)).toString("base64url")
+ },
+ decode(input: string) {
+ return Cursor.parse(JSON.parse(Buffer.from(input, "base64url").toString("utf8")))
+ },
+ }
+
+ const info = (row: typeof MessageTable.$inferSelect) =>
+ ({
+ ...row.data,
+ id: row.id,
+ sessionID: row.session_id,
+ }) as MessageV2.Info
+
+ const part = (row: typeof PartTable.$inferSelect) =>
+ ({
+ ...row.data,
+ id: row.id,
+ sessionID: row.session_id,
+ messageID: row.message_id,
+ }) as MessageV2.Part
+
+ const older = (row: Cursor) =>
+ or(
+ lt(MessageTable.time_created, row.time),
+ and(eq(MessageTable.time_created, row.time), lt(MessageTable.id, row.id)),
+ )
+
+ async function hydrate(rows: (typeof MessageTable.$inferSelect)[]) {
+ const ids = rows.map((row) => row.id)
+ const partByMessage = new Map<string, MessageV2.Part[]>()
+ if (ids.length > 0) {
+ const partRows = Database.use((db) =>
+ db
+ .select()
+ .from(PartTable)
+ .where(inArray(PartTable.message_id, ids))
+ .orderBy(PartTable.message_id, PartTable.id)
+ .all(),
+ )
+ for (const row of partRows) {
+ const next = part(row)
+ const list = partByMessage.get(row.message_id)
+ if (list) list.push(next)
+ else partByMessage.set(row.message_id, [next])
+ }
+ }
+
+ return rows.map((row) => ({
+ info: info(row),
+ parts: partByMessage.get(row.id) ?? [],
+ }))
+ }
+
export function toModelMessages(
input: WithParts[],
model: Provider.Model,
@@ -729,56 +791,61 @@ export namespace MessageV2 {
)
}
- export const stream = fn(SessionID.zod, async function* (sessionID) {
- const size = 50
- let offset = 0
- while (true) {
+ export const page = fn(
+ z.object({
+ sessionID: SessionID.zod,
+ limit: z.number().int().positive(),
+ before: z.string().optional(),
+ }),
+ async (input) => {
+ const before = input.before ? cursor.decode(input.before) : undefined
+ const where = before
+ ? and(eq(MessageTable.session_id, input.sessionID), older(before))
+ : eq(MessageTable.session_id, input.sessionID)
const rows = Database.use((db) =>
db
.select()
.from(MessageTable)
- .where(eq(MessageTable.session_id, sessionID))
- .orderBy(desc(MessageTable.time_created))
- .limit(size)
- .offset(offset)
+ .where(where)
+ .orderBy(desc(MessageTable.time_created), desc(MessageTable.id))
+ .limit(input.limit + 1)
.all(),
)
- if (rows.length === 0) break
-
- const ids = rows.map((row) => row.id)
- const partsByMessage = new Map<string, MessageV2.Part[]>()
- if (ids.length > 0) {
- const partRows = Database.use((db) =>
- db
- .select()
- .from(PartTable)
- .where(inArray(PartTable.message_id, ids))
- .orderBy(PartTable.message_id, PartTable.id)
- .all(),
+ if (rows.length === 0) {
+ const row = Database.use((db) =>
+ db.select({ id: SessionTable.id }).from(SessionTable).where(eq(SessionTable.id, input.sessionID)).get(),
)
- for (const row of partRows) {
- const part = {
- ...row.data,
- id: row.id,
- sessionID: row.session_id,
- messageID: row.message_id,
- } as MessageV2.Part
- const list = partsByMessage.get(row.message_id)
- if (list) list.push(part)
- else partsByMessage.set(row.message_id, [part])
+ if (!row) throw new NotFoundError({ message: `Session not found: ${input.sessionID}` })
+ return {
+ items: [] as MessageV2.WithParts[],
+ more: false,
}
}
- for (const row of rows) {
- const info = { ...row.data, id: row.id, sessionID: row.session_id } as MessageV2.Info
- yield {
- info,
- parts: partsByMessage.get(row.id) ?? [],
- }
+ const more = rows.length > input.limit
+ const page = more ? rows.slice(0, input.limit) : rows
+ const items = await hydrate(page)
+ items.reverse()
+ const tail = page.at(-1)
+ return {
+ items,
+ more,
+ cursor: more && tail ? cursor.encode({ id: tail.id, time: tail.time_created }) : undefined,
}
+ },
+ )
- offset += rows.length
- if (rows.length < size) break
+ export const stream = fn(SessionID.zod, async function* (sessionID) {
+ const size = 50
+ let before: string | undefined
+ while (true) {
+ const next = await page({ sessionID, limit: size, before })
+ if (next.items.length === 0) break
+ for (let i = next.items.length - 1; i >= 0; i--) {
+ yield next.items[i]
+ }
+ if (!next.more || !next.cursor) break
+ before = next.cursor
}
})
@@ -797,11 +864,16 @@ export namespace MessageV2 {
messageID: MessageID.zod,
}),
async (input): Promise<WithParts> => {
- const row = Database.use((db) => db.select().from(MessageTable).where(eq(MessageTable.id, input.messageID)).get())
- if (!row) throw new Error(`Message not found: ${input.messageID}`)
- const info = { ...row.data, id: row.id, sessionID: row.session_id } as MessageV2.Info
+ const row = Database.use((db) =>
+ db
+ .select()
+ .from(MessageTable)
+ .where(and(eq(MessageTable.id, input.messageID), eq(MessageTable.session_id, input.sessionID)))
+ .get(),
+ )
+ if (!row) throw new NotFoundError({ message: `Message not found: ${input.messageID}` })
return {
- info,
+ info: info(row),
parts: await parts(input.messageID),
}
},
diff --git a/packages/opencode/src/session/session.sql.ts b/packages/opencode/src/session/session.sql.ts
index 71abc8516..b3229edd1 100644
--- a/packages/opencode/src/session/session.sql.ts
+++ b/packages/opencode/src/session/session.sql.ts
@@ -54,7 +54,7 @@ export const MessageTable = sqliteTable(
...Timestamps,
data: text({ mode: "json" }).notNull().$type<InfoData>(),
},
- (table) => [index("message_session_idx").on(table.session_id)],
+ (table) => [index("message_session_time_created_id_idx").on(table.session_id, table.time_created, table.id)],
)
export const PartTable = sqliteTable(
@@ -69,7 +69,10 @@ export const PartTable = sqliteTable(
...Timestamps,
data: text({ mode: "json" }).notNull().$type<PartData>(),
},
- (table) => [index("part_message_idx").on(table.message_id), index("part_session_idx").on(table.session_id)],
+ (table) => [
+ index("part_message_id_id_idx").on(table.message_id, table.id),
+ index("part_session_idx").on(table.session_id),
+ ],
)
export const TodoTable = sqliteTable(
diff --git a/packages/opencode/test/server/session-messages.test.ts b/packages/opencode/test/server/session-messages.test.ts
new file mode 100644
index 000000000..ee4c51646
--- /dev/null
+++ b/packages/opencode/test/server/session-messages.test.ts
@@ -0,0 +1,119 @@
+import { describe, expect, test } from "bun:test"
+import path from "path"
+import { Instance } from "../../src/project/instance"
+import { Server } from "../../src/server/server"
+import { Session } from "../../src/session"
+import { MessageV2 } from "../../src/session/message-v2"
+import { MessageID, PartID, type SessionID } from "../../src/session/schema"
+import { Log } from "../../src/util/log"
+
+const root = path.join(__dirname, "../..")
+Log.init({ print: false })
+
+async function fill(sessionID: SessionID, count: number, time = (i: number) => Date.now() + i) {
+ const ids = [] as MessageID[]
+ for (let i = 0; i < count; i++) {
+ const id = MessageID.ascending()
+ ids.push(id)
+ await Session.updateMessage({
+ id,
+ sessionID,
+ role: "user",
+ time: { created: time(i) },
+ agent: "test",
+ model: { providerID: "test", modelID: "test" },
+ tools: {},
+ mode: "",
+ } as unknown as MessageV2.Info)
+ await Session.updatePart({
+ id: PartID.ascending(),
+ sessionID,
+ messageID: id,
+ type: "text",
+ text: `m${i}`,
+ })
+ }
+ return ids
+}
+
+describe("session messages endpoint", () => {
+ test("returns cursor headers for older pages", async () => {
+ await Instance.provide({
+ directory: root,
+ fn: async () => {
+ const session = await Session.create({})
+ const ids = await fill(session.id, 5)
+ const app = Server.Default()
+
+ const a = await app.request(`/session/${session.id}/message?limit=2`)
+ expect(a.status).toBe(200)
+ const aBody = (await a.json()) as MessageV2.WithParts[]
+ expect(aBody.map((item) => item.info.id)).toEqual(ids.slice(-2))
+ const cursor = a.headers.get("x-next-cursor")
+ expect(cursor).toBeTruthy()
+ expect(a.headers.get("link")).toContain('rel="next"')
+
+ const b = await app.request(`/session/${session.id}/message?limit=2&before=${encodeURIComponent(cursor!)}`)
+ expect(b.status).toBe(200)
+ const bBody = (await b.json()) as MessageV2.WithParts[]
+ expect(bBody.map((item) => item.info.id)).toEqual(ids.slice(-4, -2))
+
+ await Session.remove(session.id)
+ },
+ })
+ })
+
+ test("keeps full-history responses when limit is omitted", async () => {
+ await Instance.provide({
+ directory: root,
+ fn: async () => {
+ const session = await Session.create({})
+ const ids = await fill(session.id, 3)
+ const app = Server.Default()
+
+ const res = await app.request(`/session/${session.id}/message`)
+ expect(res.status).toBe(200)
+ const body = (await res.json()) as MessageV2.WithParts[]
+ expect(body.map((item) => item.info.id)).toEqual(ids)
+
+ await Session.remove(session.id)
+ },
+ })
+ })
+
+ test("rejects invalid cursors and missing sessions", async () => {
+ await Instance.provide({
+ directory: root,
+ fn: async () => {
+ const session = await Session.create({})
+ const app = Server.Default()
+
+ const bad = await app.request(`/session/${session.id}/message?limit=2&before=bad`)
+ expect(bad.status).toBe(400)
+
+ const miss = await app.request(`/session/ses_missing/message?limit=2`)
+ expect(miss.status).toBe(404)
+
+ await Session.remove(session.id)
+ },
+ })
+ })
+
+ test("does not truncate large legacy limit requests", async () => {
+ await Instance.provide({
+ directory: root,
+ fn: async () => {
+ const session = await Session.create({})
+ await fill(session.id, 520)
+ const app = Server.Default()
+
+ const res = await app.request(`/session/${session.id}/message?limit=510`)
+ expect(res.status).toBe(200)
+ const body = (await res.json()) as MessageV2.WithParts[]
+ expect(body).toHaveLength(510)
+
+ await Session.remove(session.id)
+ },
+ })
+ })
+})
diff --git a/packages/opencode/test/session/messages-pagination.test.ts b/packages/opencode/test/session/messages-pagination.test.ts
new file mode 100644
index 000000000..3614b17d0
--- /dev/null
+++ b/packages/opencode/test/session/messages-pagination.test.ts
@@ -0,0 +1,115 @@
+import { describe, expect, test } from "bun:test"
+import path from "path"
+import { Instance } from "../../src/project/instance"
+import { Session } from "../../src/session"
+import { MessageV2 } from "../../src/session/message-v2"
+import { MessageID, PartID, type SessionID } from "../../src/session/schema"
+import { Log } from "../../src/util/log"
+
+const root = path.join(__dirname, "../..")
+Log.init({ print: false })
+
+async function fill(sessionID: SessionID, count: number, time = (i: number) => Date.now() + i) {
+ const ids = [] as MessageID[]
+ for (let i = 0; i < count; i++) {
+ const id = MessageID.ascending()
+ ids.push(id)
+ await Session.updateMessage({
+ id,
+ sessionID,
+ role: "user",
+ time: { created: time(i) },
+ agent: "test",
+ model: { providerID: "test", modelID: "test" },
+ tools: {},
+ mode: "",
+ } as unknown as MessageV2.Info)
+ await Session.updatePart({
+ id: PartID.ascending(),
+ sessionID,
+ messageID: id,
+ type: "text",
+ text: `m${i}`,
+ })
+ }
+ return ids
+}
+
+describe("session message pagination", () => {
+ test("pages backward with opaque cursors", async () => {
+ await Instance.provide({
+ directory: root,
+ fn: async () => {
+ const session = await Session.create({})
+ const ids = await fill(session.id, 6)
+
+ const a = await MessageV2.page({ sessionID: session.id, limit: 2 })
+ expect(a.items.map((item) => item.info.id)).toEqual(ids.slice(-2))
+ expect(a.items.every((item) => item.parts.length === 1)).toBe(true)
+ expect(a.more).toBe(true)
+ expect(a.cursor).toBeTruthy()
+
+ const b = await MessageV2.page({ sessionID: session.id, limit: 2, before: a.cursor! })
+ expect(b.items.map((item) => item.info.id)).toEqual(ids.slice(-4, -2))
+ expect(b.more).toBe(true)
+ expect(b.cursor).toBeTruthy()
+
+ const c = await MessageV2.page({ sessionID: session.id, limit: 2, before: b.cursor! })
+ expect(c.items.map((item) => item.info.id)).toEqual(ids.slice(0, 2))
+ expect(c.more).toBe(false)
+ expect(c.cursor).toBeUndefined()
+
+ await Session.remove(session.id)
+ },
+ })
+ })
+
+ test("keeps stream order newest first", async () => {
+ await Instance.provide({
+ directory: root,
+ fn: async () => {
+ const session = await Session.create({})
+ const ids = await fill(session.id, 5)
+
+ const items = await Array.fromAsync(MessageV2.stream(session.id))
+ expect(items.map((item) => item.info.id)).toEqual(ids.slice().reverse())
+
+ await Session.remove(session.id)
+ },
+ })
+ })
+
+ test("accepts cursors generated from fractional timestamps", async () => {
+ await Instance.provide({
+ directory: root,
+ fn: async () => {
+ const session = await Session.create({})
+ const ids = await fill(session.id, 4, (i) => 1000.5 + i)
+
+ const a = await MessageV2.page({ sessionID: session.id, limit: 2 })
+ const b = await MessageV2.page({ sessionID: session.id, limit: 2, before: a.cursor! })
+
+ expect(a.items.map((item) => item.info.id)).toEqual(ids.slice(-2))
+ expect(b.items.map((item) => item.info.id)).toEqual(ids.slice(0, 2))
+
+ await Session.remove(session.id)
+ },
+ })
+ })
+
+ test("scopes get by session id", async () => {
+ await Instance.provide({
+ directory: root,
+ fn: async () => {
+ const a = await Session.create({})
+ const b = await Session.create({})
+ const [id] = await fill(a.id, 1)
+
+ await expect(MessageV2.get({ sessionID: b.id, messageID: id })).rejects.toMatchObject({ name: "NotFoundError" })
+
+ await Session.remove(a.id)
+ await Session.remove(b.id)
+ },
+ })
+ })
+})
diff --git a/packages/sdk/js/src/v2/gen/sdk.gen.ts b/packages/sdk/js/src/v2/gen/sdk.gen.ts
index 2bb2edcd1..27c188838 100644
--- a/packages/sdk/js/src/v2/gen/sdk.gen.ts
+++ b/packages/sdk/js/src/v2/gen/sdk.gen.ts
@@ -1793,6 +1793,7 @@ export class Session2 extends HeyApiClient {
directory?: string
workspace?: string
limit?: number
+ before?: string
},
options?: Options<never, ThrowOnError>,
) {
@@ -1805,6 +1806,7 @@ export class Session2 extends HeyApiClient {
{ in: "query", key: "directory" },
{ in: "query", key: "workspace" },
{ in: "query", key: "limit" },
+ { in: "query", key: "before" },
],
},
],
diff --git a/packages/sdk/js/src/v2/gen/types.gen.ts b/packages/sdk/js/src/v2/gen/types.gen.ts
index 30568c96d..2629015eb 100644
--- a/packages/sdk/js/src/v2/gen/types.gen.ts
+++ b/packages/sdk/js/src/v2/gen/types.gen.ts
@@ -3232,7 +3232,11 @@ export type SessionMessagesData = {
query?: {
directory?: string
workspace?: string
+ /**
+ * Maximum number of messages to return
+ */
limit?: number
+ before?: string
}
url: "/session/{sessionID}/message"
}
diff --git a/packages/sdk/openapi.json b/packages/sdk/openapi.json
index a5e10f0d7..569de3966 100644
--- a/packages/sdk/openapi.json
+++ b/packages/sdk/openapi.json
@@ -27,7 +27,10 @@
"type": "string"
}
},
- "required": ["healthy", "version"]
+ "required": [
+ "healthy",
+ "version"
+ ]
}
}
}
@@ -744,7 +747,10 @@
"type": "number"
}
},
- "required": ["rows", "cols"]
+ "required": [
+ "rows",
+ "cols"
+ ]
}
}
}
@@ -1021,7 +1027,10 @@
}
}
},
- "required": ["providers", "default"]
+ "required": [
+ "providers",
+ "default"
+ ]
}
}
}
@@ -1228,7 +1237,11 @@
]
}
},
- "required": ["type", "branch", "extra"]
+ "required": [
+ "type",
+ "branch",
+ "extra"
+ ]
}
}
}
@@ -1941,7 +1954,9 @@
],
"summary": "Get session",
"description": "Retrieve detailed information about a specific OpenCode session.",
- "tags": ["Session"],
+ "tags": [
+ "Session"
+ ],
"responses": {
"200": {
"description": "Get session",
@@ -2169,7 +2184,9 @@
}
],
"summary": "Get session children",
- "tags": ["Session"],
+ "tags": [
+ "Session"
+ ],
"description": "Retrieve all child sessions that were forked from the specified parent session.",
"responses": {
"200": {
@@ -2366,7 +2383,11 @@
"pattern": "^msg.*"
}
},
- "required": ["modelID", "providerID", "messageID"]
+ "required": [
+ "modelID",
+ "providerID",
+ "messageID"
+ ]
}
}
}
@@ -2792,7 +2813,10 @@
"type": "boolean"
}
},
- "required": ["providerID", "modelID"]
+ "required": [
+ "providerID",
+ "modelID"
+ ]
}
}
}
@@ -2836,7 +2860,17 @@
"in": "query",
"name": "limit",
"schema": {
- "type": "number"
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 9007199254740991
+ },
+ "description": "Maximum number of messages to return"
+ },
+ {
+ "in": "query",
+ "name": "before",
+ "schema": {
+ "type": "string"
}
}
],
@@ -2862,7 +2896,10 @@
}
}
},
- "required": ["info", "parts"]
+ "required": [
+ "info",
+ "parts"
+ ]
}
}
}
@@ -2943,7 +2980,10 @@
}
}
},
- "required": ["info", "parts"]
+ "required": [
+ "info",
+ "parts"
+ ]
}
}
}
@@ -2989,7 +3029,10 @@
"type": "string"
}
},
- "required": ["providerID", "modelID"]
+ "required": [
+ "providerID",
+ "modelID"
+ ]
},
"agent": {
"type": "string"
@@ -3036,7 +3079,9 @@
}
}
},
- "required": ["parts"]
+ "required": [
+ "parts"
+ ]
}
}
}
@@ -3106,7 +3151,10 @@
}
}
},
- "required": ["info", "parts"]
+ "required": [
+ "info",
+ "parts"
+ ]
}
}
}
@@ -3473,7 +3521,10 @@
"type": "string"
}
},
- "required": ["providerID", "modelID"]
+ "required": [
+ "providerID",
+ "modelID"
+ ]
},
"agent": {
"type": "string"
@@ -3520,7 +3571,9 @@
}
}
},
- "required": ["parts"]
+ "required": [
+ "parts"
+ ]
}
}
}
@@ -3581,7 +3634,10 @@
}
}
},
- "required": ["info", "parts"]
+ "required": [
+ "info",
+ "parts"
+ ]
}
}
}
@@ -3660,13 +3716,20 @@
"$ref": "#/components/schemas/FilePartSource"
}
},
- "required": ["type", "mime", "url"]
+ "required": [
+ "type",
+ "mime",
+ "url"
+ ]
}
]
}
}
},
- "required": ["arguments", "command"]
+ "required": [
+ "arguments",
+ "command"
+ ]
}
}
}
@@ -3760,13 +3823,19 @@
"type": "string"
}
},
- "required": ["providerID", "modelID"]
+ "required": [
+ "providerID",
+ "modelID"
+ ]
},
"command": {
"type": "string"
}
},
- "required": ["agent", "command"]
+ "required": [
+ "agent",
+ "command"
+ ]
}
}
}
@@ -3856,7 +3925,9 @@
"pattern": "^prt.*"
}
},
- "required": ["messageID"]
+ "required": [
+ "messageID"
+ ]
}
}
}
@@ -4019,10 +4090,16 @@
"properties": {
"response": {
"type": "string",
- "enum": ["once", "always", "reject"]
+ "enum": [
+ "once",
+ "always",
+ "reject"
+ ]
}
},
- "required": ["response"]
+ "required": [
+ "response"
+ ]
}
}
}
@@ -4105,13 +4182,19 @@
"properties": {
"reply": {
"type": "string",
- "enum": ["once", "always", "reject"]
+ "enum": [
+ "once",
+ "always",
+ "reject"
+ ]
},
"message": {
"type": "string"
}
},
- "required": ["reply"]
+ "required": [
+ "reply"
+ ]
}
}
}
@@ -4288,7 +4371,9 @@
}
}
},
- "required": ["answers"]
+ "required": [
+ "answers"
+ ]
}
}
}
@@ -4466,10 +4551,15 @@
"properties": {
"field": {
"type": "string",
- "enum": ["reasoning_content", "reasoning_details"]
+ "enum": [
+ "reasoning_content",
+ "reasoning_details"
+ ]
}
},
- "required": ["field"],
+ "required": [
+ "field"
+ ],
"additionalProperties": false
}
]
@@ -4505,10 +4595,16 @@
"type": "number"
}
},
- "required": ["input", "output"]
+ "required": [
+ "input",
+ "output"
+ ]
}
},
- "required": ["input", "output"]
+ "required": [
+ "input",
+ "output"
+ ]
},
"limit": {
"type": "object",
@@ -4523,7 +4619,10 @@
"type": "number"
}
},
- "required": ["context", "output"]
+ "required": [
+ "context",
+ "output"
+ ]
},
"modalities": {
"type": "object",
@@ -4532,25 +4631,44 @@
"type": "array",
"items": {
"type": "string",
- "enum": ["text", "audio", "image", "video", "pdf"]
+ "enum": [
+ "text",
+ "audio",
+ "image",
+ "video",
+ "pdf"
+ ]
}
},
"output": {
"type": "array",
"items": {
"type": "string",
- "enum": ["text", "audio", "image", "video", "pdf"]
+ "enum": [
+ "text",
+ "audio",
+ "image",
+ "video",
+ "pdf"
+ ]
}
}
},
- "required": ["input", "output"]
+ "required": [
+ "input",
+ "output"
+ ]
},
"experimental": {
"type": "boolean"
},
"status": {
"type": "string",
- "enum": ["alpha", "beta", "deprecated"]
+ "enum": [
+ "alpha",
+ "beta",
+ "deprecated"
+ ]
},
"options": {
"type": "object",
@@ -4607,7 +4725,12 @@
}
}
},
- "required": ["name", "env", "id", "models"]
+ "required": [
+ "name",
+ "env",
+ "id",
+ "models"
+ ]
}
},
"default": {
@@ -4626,7 +4749,11 @@
}
}
},
- "required": ["all", "default", "connected"]
+ "required": [
+ "all",
+ "default",
+ "connected"
+ ]
}
}
}
@@ -4753,7 +4880,9 @@
"type": "number"
}
},
- "required": ["method"]
+ "required": [
+ "method"
+ ]
}
}
}
@@ -4833,7 +4962,9 @@
"type": "string"
}
},
- "required": ["method"]
+ "required": [
+ "method"
+ ]
}
}
}
@@ -4892,7 +5023,9 @@
"type": "string"
}
},
- "required": ["text"]
+ "required": [
+ "text"
+ ]
},
"lines": {
"type": "object",
@@ -4901,7 +5034,9 @@
"type": "string"
}
},
- "required": ["text"]
+ "required": [
+ "text"
+ ]
},
"line_number": {
"type": "number"
@@ -4921,7 +5056,9 @@
"type": "string"
}
},
- "required": ["text"]
+ "required": [
+ "text"
+ ]
},
"start": {
"type": "number"
@@ -4930,11 +5067,21 @@
"type": "number"
}
},
- "required": ["match", "start", "end"]
+ "required": [
+ "match",
+ "start",
+ "end"
+ ]
}
}
},
- "required": ["path", "lines", "line_number", "absolute_offset", "submatches"]
+ "required": [
+ "path",
+ "lines",
+ "line_number",
+ "absolute_offset",
+ "submatches"
+ ]
}
}
}
@@ -4980,7 +5127,10 @@
"name": "dirs",
"schema": {
"type": "string",
- "enum": ["true", "false"]
+ "enum": [
+ "true",
+ "false"
+ ]
}
},
{
@@ -4988,7 +5138,10 @@
"name": "type",
"schema": {
"type": "string",
- "enum": ["file", "directory"]
+ "enum": [
+ "file",
+ "directory"
+ ]
}
},
{
@@ -5337,7 +5490,10 @@
]
}
},
- "required": ["name", "config"]
+ "required": [
+ "name",
+ "config"
+ ]
}
}
}
@@ -5392,7 +5548,9 @@
"type": "string"
}
},
- "required": ["authorizationUrl"]
+ "required": [
+ "authorizationUrl"
+ ]
}
}
}
@@ -5466,7 +5624,9 @@
"const": true
}
},
- "required": ["success"]
+ "required": [
+ "success"
+ ]
}
}
}
@@ -5562,7 +5722,9 @@
"type": "string"
}
},
- "required": ["code"]
+ "required": [
+ "code"
+ ]
}
}
}
@@ -5793,7 +5955,9 @@
"type": "string"
}
},
- "required": ["text"]
+ "required": [
+ "text"
+ ]
}
}
}
@@ -6105,7 +6269,9 @@
"type": "string"
}
},
- "required": ["command"]
+ "required": [
+ "command"
+ ]
}
}
}
@@ -6165,7 +6331,12 @@
},
"variant": {
"type": "string",
- "enum": ["info", "success", "warning", "error"]
+ "enum": [
+ "info",
+ "success",
+ "warning",
+ "error"
+ ]
},
"duration": {
"description": "Duration in milliseconds",
@@ -6173,7 +6344,10 @@
"type": "number"
}
},
- "required": ["message", "variant"]
+ "required": [
+ "message",
+ "variant"
+ ]
}
}
}
@@ -6324,7 +6498,9 @@
"pattern": "^ses.*"
}
},
- "required": ["sessionID"]
+ "required": [
+ "sessionID"
+ ]
}
}
}
@@ -6371,7 +6547,10 @@
},
"body": {}
},
- "required": ["path", "body"]
+ "required": [
+ "path",
+ "body"
+ ]
}
}
}
@@ -6656,7 +6835,12 @@
"level": {
"description": "Log level",
"type": "string",
- "enum": ["debug", "info", "error", "warn"]
+ "enum": [
+ "debug",
+ "info",
+ "error",
+ "warn"
+ ]
},
"message": {
"description": "Log message",
@@ -6671,7 +6855,11 @@
"additionalProperties": {}
}
},
- "required": ["service", "level", "message"]
+ "required": [
+ "service",
+ "level",
+ "message"
+ ]
}
}
}
@@ -6772,7 +6960,12 @@
"type": "string"
}
},
- "required": ["name", "description", "location", "content"]
+ "required": [
+ "name",
+ "description",
+ "location",
+ "content"
+ ]
}
}
}
@@ -6933,10 +7126,15 @@
"type": "string"
}
},
- "required": ["version"]
+ "required": [
+ "version"
+ ]
}
},
- "required": ["type", "properties"]
+ "required": [
+ "type",
+ "properties"
+ ]
},
"Event.installation.update-available": {
"type": "object",
@@ -6952,10 +7150,15 @@
"type": "string"
}
},
- "required": ["version"]
+ "required": [
+ "version"
+ ]
}
},
- "required": ["type", "properties"]
+ "required": [
+ "type",
+ "properties"
+ ]
},
"Project": {
"type": "object",
@@ -7009,7 +7212,10 @@
"type": "number"
}
},
- "required": ["created", "updated"]
+ "required": [
+ "created",
+ "updated"
+ ]
},
"sandboxes": {
"type": "array",
@@ -7018,7 +7224,12 @@
}
}
},
- "required": ["id", "worktree", "time", "sandboxes"]
+ "required": [
+ "id",
+ "worktree",
+ "time",
+ "sandboxes"
+ ]
},
"Event.project.updated": {
"type": "object",
@@ -7031,7 +7242,10 @@
"$ref": "#/components/schemas/Project"
}
},
- "required": ["type", "properties"]
+ "required": [
+ "type",
+ "properties"
+ ]
},
"Event.server.instance.disposed": {
"type": "object",
@@ -7047,10 +7261,15 @@
"type": "string"
}
},
- "required": ["directory"]
+ "required": [
+ "directory"
+ ]
}
},
- "required": ["type", "properties"]
+ "required": [
+ "type",
+ "properties"
+ ]
},
"Event.server.connected": {
"type": "object",
@@ -7064,7 +7283,10 @@
"properties": {}
}
},
- "required": ["type", "properties"]
+ "required": [
+ "type",
+ "properties"
+ ]
},
"Event.global.disposed": {
"type": "object",
@@ -7078,7 +7300,10 @@
"properties": {}
}
},
- "required": ["type", "properties"]
+ "required": [
+ "type",
+ "properties"
+ ]
},
"Event.lsp.client.diagnostics": {
"type": "object",
@@ -7097,10 +7322,16 @@
"type": "string"
}
},
- "required": ["serverID", "path"]
+ "required": [
+ "serverID",
+ "path"
+ ]
}
},
- "required": ["type", "properties"]
+ "required": [
+ "type",
+ "properties"
+ ]
},
"Event.lsp.updated": {
"type": "object",
@@ -7114,7 +7345,10 @@
"properties": {}
}
},
- "required": ["type", "properties"]
+ "required": [
+ "type",
+ "properties"
+ ]
},
"Event.file.edited": {
"type": "object",
@@ -7130,10 +7364,15 @@
"type": "string"
}
},
- "required": ["file"]
+ "required": [
+ "file"
+ ]
}
},
- "required": ["type", "properties"]
+ "required": [
+ "type",
+ "properties"
+ ]
},
"OutputFormatText": {
"type": "object",
@@ -7143,7 +7382,9 @@
"const": "text"
}
},
- "required": ["type"]
+ "required": [
+ "type"
+ ]
},
"JSONSchema": {
"type": "object",
@@ -7169,7 +7410,10 @@
"maximum": 9007199254740991
}
},
- "required": ["type", "schema"]
+ "required": [
+ "type",
+ "schema"
+ ]
},
"OutputFormat": {
"anyOf": [
@@ -7201,10 +7445,20 @@
},
"status": {
"type": "string",
- "enum": ["added", "deleted", "modified"]
+ "enum": [
+ "added",
+ "deleted",
+ "modified"
+ ]
}
},
- "required": ["file", "before", "after", "additions", "deletions"]
+ "required": [
+ "file",
+ "before",
+ "after",
+ "additions",
+ "deletions"
+ ]
},
"UserMessage": {
"type": "object",
@@ -7228,7 +7482,9 @@
"type": "number"
}
},
- "required": ["created"]
+ "required": [
+ "created"
+ ]
},
"format": {
"$ref": "#/components/schemas/OutputFormat"
@@ -7249,7 +7505,9 @@
}
}
},
- "required": ["diffs"]
+ "required": [
+ "diffs"
+ ]
},
"agent": {
"type": "string"
@@ -7264,7 +7522,10 @@
"type": "string"
}
},
- "required": ["providerID", "modelID"]
+ "required": [
+ "providerID",
+ "modelID"
+ ]
},
"system": {
"type": "string"
@@ -7282,7 +7543,14 @@
"type": "string"
}
},
- "required": ["id", "sessionID", "role", "time", "agent", "model"]
+ "required": [
+ "id",
+ "sessionID",
+ "role",
+ "time",
+ "agent",
+ "model"
+ ]
},
"ProviderAuthError": {
"type": "object",
@@ -7301,10 +7569,16 @@
"type": "string"
}
},
- "required": ["providerID", "message"]
+ "required": [
+ "providerID",
+ "message"
+ ]
}
},
- "required": ["name", "data"]
+ "required": [
+ "name",
+ "data"
+ ]
},
"UnknownError": {
"type": "object",
@@ -7320,10 +7594,15 @@
"type": "string"
}
},
- "required": ["message"]
+ "required": [
+ "message"
+ ]
}
},
- "required": ["name", "data"]
+ "required": [
+ "name",
+ "data"
+ ]
},
"MessageOutputLengthError": {
"type": "object",
@@ -7337,7 +7616,10 @@
"properties": {}
}
},
- "required": ["name", "data"]
+ "required": [
+ "name",
+ "data"
+ ]
},
"MessageAbortedError": {
"type": "object",
@@ -7353,10 +7635,15 @@
"type": "string"
}
},
- "required": ["message"]
+ "required": [
+ "message"
+ ]
}
},
- "required": ["name", "data"]
+ "required": [
+ "name",
+ "data"
+ ]
},
"StructuredOutputError": {
"type": "object",
@@ -7375,10 +7662,16 @@
"type": "number"
}
},
- "required": ["message", "retries"]
+ "required": [
+ "message",
+ "retries"
+ ]
}
},
- "required": ["name", "data"]
+ "required": [
+ "name",
+ "data"
+ ]
},
"ContextOverflowError": {
"type": "object",
@@ -7397,10 +7690,15 @@
"type": "string"
}
},
- "required": ["message"]
+ "required": [
+ "message"
+ ]
}
},
- "required": ["name", "data"]
+ "required": [
+ "name",
+ "data"
+ ]
},
"APIError": {
"type": "object",
@@ -7443,10 +7741,16 @@
}
}
},
- "required": ["message", "isRetryable"]
+ "required": [
+ "message",
+ "isRetryable"
+ ]
}
},
- "required": ["name", "data"]
+ "required": [
+ "name",
+ "data"
+ ]
},
"AssistantMessage": {
"type": "object",
@@ -7473,7 +7777,9 @@
"type": "number"
}
},
- "required": ["created"]
+ "required": [
+ "created"
+ ]
},
"error": {
"anyOf": [
@@ -7526,7 +7832,10 @@
"type": "string"
}
},
- "required": ["cwd", "root"]
+ "required": [
+ "cwd",
+ "root"
+ ]
},
"summary": {
"type": "boolean"
@@ -7559,10 +7868,18 @@
"type": "number"
}
},
- "required": ["read", "write"]
+ "required": [
+ "read",
+ "write"
+ ]
}
},
- "required": ["input", "output", "reasoning", "cache"]
+ "required": [
+ "input",
+ "output",
+ "reasoning",
+ "cache"
+ ]
},
"structured": {},
"variant": {
@@ -7611,10 +7928,15 @@
"$ref": "#/components/schemas/Message"
}
},
- "required": ["info"]
+ "required": [
+ "info"
+ ]
}
},
- "required": ["type", "properties"]
+ "required": [
+ "type",
+ "properties"
+ ]
},
"Event.message.removed": {
"type": "object",
@@ -7635,10 +7957,16 @@
"pattern": "^msg.*"
}
},
- "required": ["sessionID", "messageID"]
+ "required": [
+ "sessionID",
+ "messageID"
+ ]
}
},
- "required": ["type", "properties"]
+ "required": [
+ "type",
+ "properties"
+ ]
},
"TextPart": {
"type": "object",
@@ -7678,7 +8006,9 @@
"type": "number"
}
},
- "required": ["start"]
+ "required": [
+ "start"
+ ]
},
"metadata": {
"type": "object",
@@ -7688,7 +8018,13 @@
"additionalProperties": {}
}
},
- "required": ["id", "sessionID", "messageID", "type", "text"]
+ "required": [
+ "id",
+ "sessionID",
+ "messageID",
+ "type",
+ "text"
+ ]
},
"SubtaskPart": {
"type": "object",
@@ -7728,13 +8064,24 @@
"type": "string"
}
},
- "required": ["providerID", "modelID"]
+ "required": [
+ "providerID",
+ "modelID"
+ ]
},
"command": {
"type": "string"
}
},
- "required": ["id", "sessionID", "messageID", "type", "prompt", "description", "agent"]
+ "required": [
+ "id",
+ "sessionID",
+ "messageID",
+ "type",
+ "prompt",
+ "description",
+ "agent"
+ ]
},
"ReasoningPart": {
"type": "object",
@@ -7775,10 +8122,19 @@
"type": "number"
}
},
- "required": ["start"]
+ "required": [
+ "start"
+ ]
}
},
- "required": ["id", "sessionID", "messageID", "type", "text", "time"]
+ "required": [
+ "id",
+ "sessionID",
+ "messageID",
+ "type",
+ "text",
+ "time"
+ ]
},
"FilePartSourceText": {
"type": "object",
@@ -7797,7 +8153,11 @@
"maximum": 9007199254740991
}
},
- "required": ["value", "start", "end"]
+ "required": [
+ "value",
+ "start",
+ "end"
+ ]
},
"FileSource": {
"type": "object",
@@ -7813,7 +8173,11 @@
"type": "string"
}
},
- "required": ["text", "type", "path"]
+ "required": [
+ "text",
+ "type",
+ "path"
+ ]
},
"Range": {
"type": "object",
@@ -7828,7 +8192,10 @@
"type": "number"
}
},
- "required": ["line", "character"]
+ "required": [
+ "line",
+ "character"
+ ]
},
"end": {
"type": "object",
@@ -7840,10 +8207,16 @@
"type": "number"
}
},
- "required": ["line", "character"]
+ "required": [
+ "line",
+ "character"
+ ]
}
},
- "required": ["start", "end"]
+ "required": [
+ "start",
+ "end"
+ ]
},
"SymbolSource": {
"type": "object",
@@ -7870,7 +8243,14 @@
"maximum": 9007199254740991
}
},
- "required": ["text", "type", "path", "range", "name", "kind"]
+ "required": [
+ "text",
+ "type",
+ "path",
+ "range",
+ "name",
+ "kind"
+ ]
},
"ResourceSource": {
"type": "object",
@@ -7889,7 +8269,12 @@
"type": "string"
}
},
- "required": ["text", "type", "clientName", "uri"]
+ "required": [
+ "text",
+ "type",
+ "clientName",
+ "uri"
+ ]
},
"FilePartSource": {
"anyOf": [
@@ -7936,7 +8321,14 @@
"$ref": "#/components/schemas/FilePartSource"
}
},
- "required": ["id", "sessionID", "messageID", "type", "mime", "url"]
+ "required": [
+ "id",
+ "sessionID",
+ "messageID",
+ "type",
+ "mime",
+ "url"
+ ]
},
"ToolStatePending": {
"type": "object",
@@ -7956,7 +8348,11 @@
"type": "string"
}
},
- "required": ["status", "input", "raw"]
+ "required": [
+ "status",
+ "input",
+ "raw"
+ ]
},
"ToolStateRunning": {
"type": "object",
@@ -7989,10 +8385,16 @@
"type": "number"
}
},
- "required": ["start"]
+ "required": [
+ "start"
+ ]
}
},
- "required": ["status", "input", "time"]
+ "required": [
+ "status",
+ "input",
+ "time"
+ ]
},
"ToolStateCompleted": {
"type": "object",
@@ -8034,7 +8436,10 @@
"type": "number"
}
},
- "required": ["start", "end"]
+ "required": [
+ "start",
+ "end"
+ ]
},
"attachments": {
"type": "array",
@@ -8043,7 +8448,14 @@
}
}
},
- "required": ["status", "input", "output", "title", "metadata", "time"]
+ "required": [
+ "status",
+ "input",
+ "output",
+ "title",
+ "metadata",
+ "time"
+ ]
},
"ToolStateError": {
"type": "object",
@@ -8079,10 +8491,18 @@
"type": "number"
}
},
- "required": ["start", "end"]
+ "required": [
+ "start",
+ "end"
+ ]
}
},
- "required": ["status", "input", "error", "time"]
+ "required": [
+ "status",
+ "input",
+ "error",
+ "time"
+ ]
},
"ToolState": {
"anyOf": [
@@ -8136,7 +8556,15 @@
"additionalProperties": {}
}
},
- "required": ["id", "sessionID", "messageID", "type", "callID", "tool", "state"]
+ "required": [
+ "id",
+ "sessionID",
+ "messageID",
+ "type",
+ "callID",
+ "tool",
+ "state"
+ ]
},
"StepStartPart": {
"type": "object",
@@ -8161,7 +8589,12 @@
"type": "string"
}
},
- "required": ["id", "sessionID", "messageID", "type"]
+ "required": [
+ "id",
+ "sessionID",
+ "messageID",
+ "type"
+ ]
},
"StepFinishPart": {
"type": "object",
@@ -8216,13 +8649,29 @@
"type": "number"
}
},
- "required": ["read", "write"]
+ "required": [
+ "read",
+ "write"
+ ]
}
},
- "required": ["input", "output", "reasoning", "cache"]
+ "required": [
+ "input",
+ "output",
+ "reasoning",
+ "cache"
+ ]
}
},
- "required": ["id", "sessionID", "messageID", "type", "reason", "cost", "tokens"]
+ "required": [
+ "id",
+ "sessionID",
+ "messageID",
+ "type",
+ "reason",
+ "cost",
+ "tokens"
+ ]
},
"SnapshotPart": {
"type": "object",
@@ -8247,7 +8696,13 @@
"type": "string"
}
},
- "required": ["id", "sessionID", "messageID", "type", "snapshot"]
+ "required": [
+ "id",
+ "sessionID",
+ "messageID",
+ "type",
+ "snapshot"
+ ]
},
"PatchPart": {
"type": "object",
@@ -8278,7 +8733,14 @@
}
}
},
- "required": ["id", "sessionID", "messageID", "type", "hash", "files"]
+ "required": [
+ "id",
+ "sessionID",
+ "messageID",
+ "type",
+ "hash",
+ "files"
+ ]
},
"AgentPart": {
"type": "object",
@@ -8319,10 +8781,20 @@
"maximum": 9007199254740991
}
},
- "required": ["value", "start", "end"]
+ "required": [
+ "value",
+ "start",
+ "end"
+ ]
}
},
- "required": ["id", "sessionID", "messageID", "type", "name"]
+ "required": [
+ "id",
+ "sessionID",
+ "messageID",
+ "type",
+ "name"
+ ]
},
"RetryPart": {
"type": "object",
@@ -8356,10 +8828,20 @@
"type": "number"
}
},
- "required": ["created"]
+ "required": [
+ "created"
+ ]
}
},
- "required": ["id", "sessionID", "messageID", "type", "attempt", "error", "time"]
+ "required": [
+ "id",
+ "sessionID",
+ "messageID",
+ "type",
+ "attempt",
+ "error",
+ "time"
+ ]
},
"CompactionPart": {
"type": "object",
@@ -8387,7 +8869,13 @@
"type": "boolean"
}
},
- "required": ["id", "sessionID", "messageID", "type", "auto"]
+ "required": [
+ "id",
+ "sessionID",
+ "messageID",
+ "type",
+ "auto"
+ ]
},
"Part": {
"anyOf": [
@@ -8443,10 +8931,15 @@
"$ref": "#/components/schemas/Part"
}
},
- "required": ["part"]
+ "required": [
+ "part"
+ ]
}
},
- "required": ["type", "properties"]
+ "required": [
+ "type",
+ "properties"
+ ]
},
"Event.message.part.delta": {
"type": "object",
@@ -8477,10 +8970,19 @@
"type": "string"
}
},
- "required": ["sessionID", "messageID", "partID", "field", "delta"]
+ "required": [
+ "sessionID",
+ "messageID",
+ "partID",
+ "field",
+ "delta"
+ ]
}
},
- "required": ["type", "properties"]
+ "required": [
+ "type",
+ "properties"
+ ]
},
"Event.message.part.removed": {
"type": "object",
@@ -8505,10 +9007,17 @@
"pattern": "^prt.*"
}
},
- "required": ["sessionID", "messageID", "partID"]
+ "required": [
+ "sessionID",
+ "messageID",
+ "partID"
+ ]
}
},
- "required": ["type", "properties"]
+ "required": [
+ "type",
+ "properties"
+ ]
},
"PermissionRequest": {
"type": "object",
@@ -8554,10 +9063,20 @@
"type": "string"
}
},
- "required": ["messageID", "callID"]
+ "required": [
+ "messageID",
+ "callID"
+ ]
}
},
- "required": ["id", "sessionID", "permission", "patterns", "metadata", "always"]
+ "required": [
+ "id",
+ "sessionID",
+ "permission",
+ "patterns",
+ "metadata",
+ "always"
+ ]
},
"Event.permission.asked": {
"type": "object",
@@ -8570,7 +9089,10 @@
"$ref": "#/components/schemas/PermissionRequest"
}
},
- "required": ["type", "properties"]
+ "required": [
+ "type",
+ "properties"
+ ]
},
"Event.permission.replied": {
"type": "object",
@@ -8592,13 +9114,24 @@
},
"reply": {
"type": "string",
- "enum": ["once", "always", "reject"]
+ "enum": [
+ "once",
+ "always",
+ "reject"
+ ]
}
},
- "required": ["sessionID", "requestID", "reply"]
+ "required": [
+ "sessionID",
+ "requestID",
+ "reply"
+ ]
}
},
- "required": ["type", "properties"]
+ "required": [
+ "type",
+ "properties"
+ ]
},
"SessionStatus": {
"anyOf": [
@@ -8610,7 +9143,9 @@
"const": "idle"
}
},
- "required": ["type"]
+ "required": [
+ "type"
+ ]
},
{
"type": "object",
@@ -8629,7 +9164,12 @@
"type": "number"
}
},
- "required": ["type", "attempt", "message", "next"]
+ "required": [
+ "type",
+ "attempt",
+ "message",
+ "next"
+ ]
},
{
"type": "object",
@@ -8639,7 +9179,9 @@
"const": "busy"
}
},
- "required": ["type"]
+ "required": [
+ "type"
+ ]
}
]
},
@@ -8661,10 +9203,16 @@
"$ref": "#/components/schemas/SessionStatus"
}
},
- "required": ["sessionID", "status"]
+ "required": [
+ "sessionID",
+ "status"
+ ]
}
},
- "required": ["type", "properties"]
+ "required": [
+ "type",
+ "properties"
+ ]
},
"Event.session.idle": {
"type": "object",
@@ -8681,10 +9229,15 @@
"pattern": "^ses.*"
}
},
- "required": ["sessionID"]
+ "required": [
+ "sessionID"
+ ]
}
},
- "required": ["type", "properties"]
+ "required": [
+ "type",
+ "properties"
+ ]
},
"QuestionOption": {
"type": "object",
@@ -8698,7 +9251,10 @@
"type": "string"
}
},
- "required": ["label", "description"]
+ "required": [
+ "label",
+ "description"
+ ]
},
"QuestionInfo": {
"type": "object",
@@ -8727,7 +9283,11 @@
"type": "boolean"
}
},
- "required": ["question", "header", "options"]
+ "required": [
+ "question",
+ "header",
+ "options"
+ ]
},
"QuestionRequest": {
"type": "object",
@@ -8758,10 +9318,17 @@
"type": "string"
}
},
- "required": ["messageID", "callID"]
+ "required": [
+ "messageID",
+ "callID"
+ ]
}
},
- "required": ["id", "sessionID", "questions"]
+ "required": [
+ "id",
+ "sessionID",
+ "questions"
+ ]
},
"Event.question.asked": {
"type": "object",
@@ -8774,7 +9341,10 @@
"$ref": "#/components/schemas/QuestionRequest"
}
},
- "required": ["type", "properties"]
+ "required": [
+ "type",
+ "properties"
+ ]
},
"QuestionAnswer": {
"type": "array",
@@ -8807,10 +9377,17 @@
}
}
},
- "required": ["sessionID", "requestID", "answers"]
+ "required": [
+ "sessionID",
+ "requestID",
+ "answers"
+ ]
}
},
- "required": ["type", "properties"]
+ "required": [
+ "type",
+ "properties"
+ ]
},
"Event.question.rejected": {
"type": "object",
@@ -8831,10 +9408,16 @@
"pattern": "^que.*"
}
},
- "required": ["sessionID", "requestID"]
+ "required": [
+ "sessionID",
+ "requestID"
+ ]
}
},
- "required": ["type", "properties"]
+ "required": [
+ "type",
+ "properties"
+ ]
},
"Event.session.compacted": {
"type": "object",
@@ -8851,10 +9434,15 @@
"pattern": "^ses.*"
}
},
- "required": ["sessionID"]
+ "required": [
+ "sessionID"
+ ]
}
},
- "required": ["type", "properties"]
+ "required": [
+ "type",
+ "properties"
+ ]
},
"Event.file.watcher.updated": {
"type": "object",
@@ -8886,10 +9474,16 @@
]
}
},
- "required": ["file", "event"]
+ "required": [
+ "file",
+ "event"
+ ]
}
},
- "required": ["type", "properties"]
+ "required": [
+ "type",
+ "properties"
+ ]
},
"Todo": {
"type": "object",
@@ -8907,7 +9501,11 @@
"type": "string"
}
},
- "required": ["content", "status", "priority"]
+ "required": [
+ "content",
+ "status",
+ "priority"
+ ]
},
"Event.todo.updated": {
"type": "object",
@@ -8930,10 +9528,16 @@
}
}
},
- "required": ["sessionID", "todos"]
+ "required": [
+ "sessionID",
+ "todos"
+ ]
}
},
- "required": ["type", "properties"]
+ "required": [
+ "type",
+ "properties"
+ ]
},
"Event.tui.prompt.append": {
"type": "object",
@@ -8949,10 +9553,15 @@
"type": "string"
}
},
- "required": ["text"]
+ "required": [
+ "text"
+ ]
}
},
- "required": ["type", "properties"]
+ "required": [
+ "type",
+ "properties"
+ ]
},
"Event.tui.command.execute": {
"type": "object",
@@ -8993,10 +9602,15 @@
]
}
},
- "required": ["command"]
+ "required": [
+ "command"
+ ]
}
},
- "required": ["type", "properties"]
+ "required": [
+ "type",
+ "properties"
+ ]
},
"Event.tui.toast.show": {
"type": "object",
@@ -9016,7 +9630,12 @@
},
"variant": {
"type": "string",
- "enum": ["info", "success", "warning", "error"]
+ "enum": [
+ "info",
+ "success",
+ "warning",
+ "error"
+ ]
},
"duration": {
"description": "Duration in milliseconds",
@@ -9024,10 +9643,16 @@
"type": "number"
}
},
- "required": ["message", "variant"]
+ "required": [
+ "message",
+ "variant"
+ ]
}
},
- "required": ["type", "properties"]
+ "required": [
+ "type",
+ "properties"
+ ]
},
"Event.tui.session.select": {
"type": "object",
@@ -9045,10 +9670,15 @@
"pattern": "^ses.*"
}
},
- "required": ["sessionID"]
+ "required": [
+ "sessionID"
+ ]
}
},
- "required": ["type", "properties"]
+ "required": [
+ "type",
+ "properties"
+ ]
},
"Event.mcp.tools.changed": {
"type": "object",
@@ -9064,10 +9694,15 @@
"type": "string"
}
},
- "required": ["server"]
+ "required": [
+ "server"
+ ]
}
},
- "required": ["type", "properties"]
+ "required": [
+ "type",
+ "properties"
+ ]
},
"Event.mcp.browser.open.failed": {
"type": "object",
@@ -9086,10 +9721,16 @@
"type": "string"
}
},
- "required": ["mcpName", "url"]
+ "required": [
+ "mcpName",
+ "url"
+ ]
}
},
- "required": ["type", "properties"]
+ "required": [
+ "type",
+ "properties"
+ ]
},
"Event.command.executed": {
"type": "object",
@@ -9116,14 +9757,26 @@
"pattern": "^msg.*"
}
},
- "required": ["name", "sessionID", "arguments", "messageID"]
+ "required": [
+ "name",
+ "sessionID",
+ "arguments",
+ "messageID"
+ ]
}
},
- "required": ["type", "properties"]
+ "required": [
+ "type",
+ "properties"
+ ]
},
"PermissionAction": {
"type": "string",
- "enum": ["allow", "deny", "ask"]
+ "enum": [
+ "allow",
+ "deny",
+ "ask"
+ ]
},
"PermissionRule": {
"type": "object",
@@ -9138,7 +9791,11 @@
"$ref": "#/components/schemas/PermissionAction"
}
},
- "required": ["permission", "pattern", "action"]
+ "required": [
+ "permission",
+ "pattern",
+ "action"
+ ]
},
"PermissionRuleset": {
"type": "array",
@@ -9189,7 +9846,11 @@
}
}
},
- "required": ["additions", "deletions", "files"]
+ "required": [
+ "additions",
+ "deletions",
+ "files"
+ ]
},
"share": {
"type": "object",
@@ -9198,7 +9859,9 @@
"type": "string"
}
},
- "required": ["url"]
+ "required": [
+ "url"
+ ]
},
"title": {
"type": "string"
@@ -9222,7 +9885,10 @@
"type": "number"
}
},
- "required": ["created", "updated"]
+ "required": [
+ "created",
+ "updated"
+ ]
},
"permission": {
"$ref": "#/components/schemas/PermissionRuleset"
@@ -9245,10 +9911,20 @@
"type": "string"
}
},
- "required": ["messageID"]
+ "required": [
+ "messageID"
+ ]
}
},
- "required": ["id", "slug", "projectID", "directory", "title", "version", "time"]
+ "required": [
+ "id",
+ "slug",
+ "projectID",
+ "directory",
+ "title",
+ "version",
+ "time"
+ ]
},
"Event.session.created": {
"type": "object",
@@ -9264,10 +9940,15 @@
"$ref": "#/components/schemas/Session"
}
},
- "required": ["info"]
+ "required": [
+ "info"
+ ]
}
},
- "required": ["type", "properties"]
+ "required": [
+ "type",
+ "properties"
+ ]
},
"Event.session.updated": {
"type": "object",
@@ -9283,10 +9964,15 @@
"$ref": "#/components/schemas/Session"
}
},
- "required": ["info"]
+ "required": [
+ "info"
+ ]
}
},
- "required": ["type", "properties"]
+ "required": [
+ "type",
+ "properties"
+ ]
},
"Event.session.deleted": {
"type": "object",
@@ -9302,10 +9988,15 @@
"$ref": "#/components/schemas/Session"
}
},
- "required": ["info"]
+ "required": [
+ "info"
+ ]
}
},
- "required": ["type", "properties"]
+ "required": [
+ "type",
+ "properties"
+ ]
},
"Event.session.diff": {
"type": "object",
@@ -9328,10 +10019,16 @@
}
}
},
- "required": ["sessionID", "diff"]
+ "required": [
+ "sessionID",
+ "diff"
+ ]
}
},
- "required": ["type", "properties"]
+ "required": [
+ "type",
+ "properties"
+ ]
},
"Event.session.error": {
"type": "object",
@@ -9375,7 +10072,10 @@
}
}
},
- "required": ["type", "properties"]
+ "required": [
+ "type",
+ "properties"
+ ]
},
"Event.vcs.branch.updated": {
"type": "object",
@@ -9393,7 +10093,10 @@
}
}
},
- "required": ["type", "properties"]
+ "required": [
+ "type",
+ "properties"
+ ]
},
"Event.workspace.ready": {
"type": "object",
@@ -9409,10 +10112,15 @@
"type": "string"
}
},
- "required": ["name"]
+ "required": [
+ "name"
+ ]
}
},
- "required": ["type", "properties"]
+ "required": [
+ "type",
+ "properties"
+ ]
},
"Event.workspace.failed": {
"type": "object",
@@ -9428,10 +10136,15 @@
"type": "string"
}
},
- "required": ["message"]
+ "required": [
+ "message"
+ ]
}
},
- "required": ["type", "properties"]
+ "required": [
+ "type",
+ "properties"
+ ]
},
"Pty": {
"type": "object",
@@ -9457,13 +10170,24 @@
},
"status": {
"type": "string",
- "enum": ["running", "exited"]
+ "enum": [
+ "running",
+ "exited"
+ ]
},
"pid": {
"type": "number"
}
},
- "required": ["id", "title", "command", "args", "cwd", "status", "pid"]
+ "required": [
+ "id",
+ "title",
+ "command",
+ "args",
+ "cwd",
+ "status",
+ "pid"
+ ]
},
"Event.pty.created": {
"type": "object",
@@ -9479,10 +10203,15 @@
"$ref": "#/components/schemas/Pty"
}
},
- "required": ["info"]
+ "required": [
+ "info"
+ ]
}
},
- "required": ["type", "properties"]
+ "required": [
+ "type",
+ "properties"
+ ]
},
"Event.pty.updated": {
"type": "object",
@@ -9498,10 +10227,15 @@
"$ref": "#/components/schemas/Pty"
}
},
- "required": ["info"]
+ "required": [
+ "info"
+ ]
}
},
- "required": ["type", "properties"]
+ "required": [
+ "type",
+ "properties"
+ ]
},
"Event.pty.exited": {
"type": "object",
@@ -9521,10 +10255,16 @@
"type": "number"
}
},
- "required": ["id", "exitCode"]
+ "required": [
+ "id",
+ "exitCode"
+ ]
}
},
- "required": ["type", "properties"]
+ "required": [
+ "type",
+ "properties"
+ ]
},
"Event.pty.deleted": {
"type": "object",
@@ -9541,10 +10281,15 @@
"pattern": "^pty.*"
}
},
- "required": ["id"]
+ "required": [
+ "id"
+ ]
}
},
- "required": ["type", "properties"]
+ "required": [
+ "type",
+ "properties"
+ ]
},
"Event.worktree.ready": {
"type": "object",
@@ -9563,10 +10308,16 @@
"type": "string"
}
},
- "required": ["name", "branch"]
+ "required": [
+ "name",
+ "branch"
+ ]
}
},
- "required": ["type", "properties"]
+ "required": [
+ "type",
+ "properties"
+ ]
},
"Event.worktree.failed": {
"type": "object",
@@ -9582,10 +10333,15 @@
"type": "string"
}
},
- "required": ["message"]
+ "required": [
+ "message"
+ ]
}
},
- "required": ["type", "properties"]
+ "required": [
+ "type",
+ "properties"
+ ]
},
"Event": {
"anyOf": [
@@ -9736,12 +10492,20 @@
"$ref": "#/components/schemas/Event"
}
},
- "required": ["directory", "payload"]
+ "required": [
+ "directory",
+ "payload"
+ ]
},
"LogLevel": {
"description": "Log level",
"type": "string",
- "enum": ["DEBUG", "INFO", "WARN", "ERROR"]
+ "enum": [
+ "DEBUG",
+ "INFO",
+ "WARN",
+ "ERROR"
+ ]
},
"ServerConfig": {
"description": "Server configuration for opencode serve and web commands",
@@ -9777,7 +10541,11 @@
},
"PermissionActionConfig": {
"type": "string",
- "enum": ["ask", "allow", "deny"]
+ "enum": [
+ "ask",
+ "allow",
+ "deny"
+ ]
},
"PermissionObjectConfig": {
"type": "object",
@@ -9908,7 +10676,11 @@
},
"mode": {
"type": "string",
- "enum": ["subagent", "primary", "all"]
+ "enum": [
+ "subagent",
+ "primary",
+ "all"
+ ]
},
"hidden": {
"description": "Hide this subagent from the @ autocomplete menu (default: false, only applies to mode: subagent)",
@@ -9930,7 +10702,15 @@
},
{
"type": "string",
- "enum": ["primary", "secondary", "accent", "success", "warning", "error", "info"]
+ "enum": [
+ "primary",
+ "secondary",
+ "accent",
+ "success",
+ "warning",
+ "error",
+ "info"
+ ]
}
]
},
@@ -10016,10 +10796,15 @@
"properties": {
"field": {
"type": "string",
- "enum": ["reasoning_content", "reasoning_details"]
+ "enum": [
+ "reasoning_content",
+ "reasoning_details"
+ ]
}
},
- "required": ["field"],
+ "required": [
+ "field"
+ ],
"additionalProperties": false
}
]
@@ -10055,10 +10840,16 @@
"type": "number"
}
},
- "required": ["input", "output"]
+ "required": [
+ "input",
+ "output"
+ ]
}
},
- "required": ["input", "output"]
+ "required": [
+ "input",
+ "output"
+ ]
},
"limit": {
"type": "object",
@@ -10073,7 +10864,10 @@
"type": "number"
}
},
- "required": ["context", "output"]
+ "required": [
+ "context",
+ "output"
+ ]
},
"modalities": {
"type": "object",
@@ -10082,25 +10876,44 @@
"type": "array",
"items": {
"type": "string",
- "enum": ["text", "audio", "image", "video", "pdf"]
+ "enum": [
+ "text",
+ "audio",
+ "image",
+ "video",
+ "pdf"
+ ]
}
},
"output": {
"type": "array",
"items": {
"type": "string",
- "enum": ["text", "audio", "image", "video", "pdf"]
+ "enum": [
+ "text",
+ "audio",
+ "image",
+ "video",
+ "pdf"
+ ]
}
}
},
- "required": ["input", "output"]
+ "required": [
+ "input",
+ "output"
+ ]
},
"experimental": {
"type": "boolean"
},
"status": {
"type": "string",
- "enum": ["alpha", "beta", "deprecated"]
+ "enum": [
+ "alpha",
+ "beta",
+ "deprecated"
+ ]
},
"options": {
"type": "object",
@@ -10242,7 +11055,10 @@
"maximum": 9007199254740991
}
},
- "required": ["type", "command"],
+ "required": [
+ "type",
+ "command"
+ ],
"additionalProperties": false
},
"McpOAuthConfig": {
@@ -10308,13 +11124,19 @@
"maximum": 9007199254740991
}
},
- "required": ["type", "url"],
+ "required": [
+ "type",
+ "url"
+ ],
"additionalProperties": false
},
"LayoutConfig": {
"description": "@deprecated Always uses stretch layout.",
"type": "string",
- "enum": ["auto", "stretch"]
+ "enum": [
+ "auto",
+ "stretch"
+ ]
},
"Config": {
"type": "object",
@@ -10354,7 +11176,9 @@
"type": "boolean"
}
},
- "required": ["template"]
+ "required": [
+ "template"
+ ]
}
},
"skills": {
@@ -10400,7 +11224,11 @@
"share": {
"description": "Control sharing behavior:'manual' allows manual sharing via commands, 'auto' enables automatic sharing, 'disabled' disables all sharing",
"type": "string",
- "enum": ["manual", "auto", "disabled"]
+ "enum": [
+ "manual",
+ "auto",
+ "disabled"
+ ]
},
"autoshare": {
"description": "@deprecated Use 'share' field instead. Share newly created sessions automatically",
@@ -10528,7 +11356,9 @@
"type": "boolean"
}
},
- "required": ["enabled"],
+ "required": [
+ "enabled"
+ ],
"additionalProperties": false
}
]
@@ -10598,7 +11428,9 @@
"const": true
}
},
- "required": ["disabled"]
+ "required": [
+ "disabled"
+ ]
},
{
"type": "object",
@@ -10635,7 +11467,9 @@
"additionalProperties": {}
}
},
- "required": ["command"]
+ "required": [
+ "command"
+ ]
}
]
}
@@ -10747,7 +11581,11 @@
"const": false
}
},
- "required": ["data", "errors", "success"]
+ "required": [
+ "data",
+ "errors",
+ "success"
+ ]
},
"OAuth": {
"type": "object",
@@ -10772,7 +11610,12 @@
"type": "string"
}
},
- "required": ["type", "refresh", "access", "expires"]
+ "required": [
+ "type",
+ "refresh",
+ "access",
+ "expires"
+ ]
},
"ApiAuth": {
"type": "object",
@@ -10785,7 +11628,10 @@
"type": "string"
}
},
- "required": ["type", "key"]
+ "required": [
+ "type",
+ "key"
+ ]
},
"WellKnownAuth": {
"type": "object",
@@ -10801,7 +11647,11 @@
"type": "string"
}
},
- "required": ["type", "key", "token"]
+ "required": [
+ "type",
+ "key",
+ "token"
+ ]
},
"Auth": {
"anyOf": [
@@ -10830,10 +11680,15 @@
"type": "string"
}
},
- "required": ["message"]
+ "required": [
+ "message"
+ ]
}
},
- "required": ["name", "data"]
+ "required": [
+ "name",
+ "data"
+ ]
},
"Model": {
"type": "object",
@@ -10857,7 +11712,11 @@
"type": "string"
}
},
- "required": ["id", "url", "npm"]
+ "required": [
+ "id",
+ "url",
+ "npm"
+ ]
},
"name": {
"type": "string"
@@ -10899,7 +11758,13 @@
"type": "boolean"
}
},
- "required": ["text", "audio", "image", "video", "pdf"]
+ "required": [
+ "text",
+ "audio",
+ "image",
+ "video",
+ "pdf"
+ ]
},
"output": {
"type": "object",
@@ -10920,7 +11785,13 @@
"type": "boolean"
}
},
- "required": ["text", "audio", "image", "video", "pdf"]
+ "required": [
+ "text",
+ "audio",
+ "image",
+ "video",
+ "pdf"
+ ]
},
"interleaved": {
"anyOf": [
@@ -10932,15 +11803,28 @@
"properties": {
"field": {
"type": "string",
- "enum": ["reasoning_content", "reasoning_details"]
+ "enum": [
+ "reasoning_content",
+ "reasoning_details"
+ ]
}
},
- "required": ["field"]
+ "required": [
+ "field"
+ ]
}
]
}
},
- "required": ["temperature", "reasoning", "attachment", "toolcall", "input", "output", "interleaved"]
+ "required": [
+ "temperature",
+ "reasoning",
+ "attachment",
+ "toolcall",
+ "input",
+ "output",
+ "interleaved"
+ ]
},
"cost": {
"type": "object",
@@ -10961,7 +11845,10 @@
"type": "number"
}
},
- "required": ["read", "write"]
+ "required": [
+ "read",
+ "write"
+ ]
},
"experimentalOver200K": {
"type": "object",
@@ -10982,13 +11869,24 @@
"type": "number"
}
},
- "required": ["read", "write"]
+ "required": [
+ "read",
+ "write"
+ ]
}
},
- "required": ["input", "output", "cache"]
+ "required": [
+ "input",
+ "output",
+ "cache"
+ ]
}
},
- "required": ["input", "output", "cache"]
+ "required": [
+ "input",
+ "output",
+ "cache"
+ ]
},
"limit": {
"type": "object",
@@ -11003,11 +11901,19 @@
"type": "number"
}
},
- "required": ["context", "output"]
+ "required": [
+ "context",
+ "output"
+ ]
},
"status": {
"type": "string",
- "enum": ["alpha", "beta", "deprecated", "active"]
+ "enum": [
+ "alpha",
+ "beta",
+ "deprecated",
+ "active"
+ ]
},
"options": {
"type": "object",
@@ -11067,7 +11973,12 @@
},
"source": {
"type": "string",
- "enum": ["env", "config", "custom", "api"]
+ "enum": [
+ "env",
+ "config",
+ "custom",
+ "api"
+ ]
},
"env": {
"type": "array",
@@ -11095,7 +12006,14 @@
}
}
},
- "required": ["id", "name", "source", "env", "options", "models"]
+ "required": [
+ "id",
+ "name",
+ "source",
+ "env",
+ "options",
+ "models"
+ ]
},
"ToolIDs": {
"type": "array",
@@ -11114,7 +12032,11 @@
},
"parameters": {}
},
- "required": ["id", "description", "parameters"]
+ "required": [
+ "id",
+ "description",
+ "parameters"
+ ]
},
"ToolList": {
"type": "array",
@@ -11174,7 +12096,15 @@
"type": "string"
}
},
- "required": ["id", "type", "branch", "name", "directory", "extra", "projectID"]
+ "required": [
+ "id",
+ "type",
+ "branch",
+ "name",
+ "directory",
+ "extra",
+ "projectID"
+ ]
},
"Worktree": {
"type": "object",
@@ -11189,7 +12119,11 @@
"type": "string"
}
},
- "required": ["name", "branch", "directory"]
+ "required": [
+ "name",
+ "branch",
+ "directory"
+ ]
},
"WorktreeCreateInput": {
"type": "object",
@@ -11210,7 +12144,9 @@
"type": "string"
}
},
- "required": ["directory"]
+ "required": [
+ "directory"
+ ]
},
"WorktreeResetInput": {
"type": "object",
@@ -11219,7 +12155,9 @@
"type": "string"
}
},
- "required": ["directory"]
+ "required": [
+ "directory"
+ ]
},
"ProjectSummary": {
"type": "object",
@@ -11234,7 +12172,10 @@
"type": "string"
}
},
- "required": ["id", "worktree"]
+ "required": [
+ "id",
+ "worktree"
+ ]
},
"GlobalSession": {
"type": "object",
@@ -11279,7 +12220,11 @@
}
}
},
- "required": ["additions", "deletions", "files"]
+ "required": [
+ "additions",
+ "deletions",
+ "files"
+ ]
},
"share": {
"type": "object",
@@ -11288,7 +12233,9 @@
"type": "string"
}
},
- "required": ["url"]
+ "required": [
+ "url"
+ ]
},
"title": {
"type": "string"
@@ -11312,7 +12259,10 @@
"type": "number"
}
},
- "required": ["created", "updated"]
+ "required": [
+ "created",
+ "updated"
+ ]
},
"permission": {
"$ref": "#/components/schemas/PermissionRuleset"
@@ -11335,7 +12285,9 @@
"type": "string"
}
},
- "required": ["messageID"]
+ "required": [
+ "messageID"
+ ]
},
"project": {
"anyOf": [
@@ -11348,7 +12300,16 @@
]
}
},
- "required": ["id", "slug", "projectID", "directory", "title", "version", "time", "project"]
+ "required": [
+ "id",
+ "slug",
+ "projectID",
+ "directory",
+ "title",
+ "version",
+ "time",
+ "project"
+ ]
},
"McpResource": {
"type": "object",
@@ -11369,7 +12330,11 @@
"type": "string"
}
},
- "required": ["name", "uri", "client"]
+ "required": [
+ "name",
+ "uri",
+ "client"
+ ]
},
"TextPartInput": {
"type": "object",
@@ -11401,7 +12366,9 @@
"type": "number"
}
},
- "required": ["start"]
+ "required": [
+ "start"
+ ]
},
"metadata": {
"type": "object",
@@ -11411,7 +12378,10 @@
"additionalProperties": {}
}
},
- "required": ["type", "text"]
+ "required": [
+ "type",
+ "text"
+ ]
},
"FilePartInput": {
"type": "object",
@@ -11437,7 +12407,11 @@
"$ref": "#/components/schemas/FilePartSource"
}
},
- "required": ["type", "mime", "url"]
+ "required": [
+ "type",
+ "mime",
+ "url"
+ ]
},
"AgentPartInput": {
"type": "object",
@@ -11470,10 +12444,17 @@
"maximum": 9007199254740991
}
},
- "required": ["value", "start", "end"]
+ "required": [
+ "value",
+ "start",
+ "end"
+ ]
}
},
- "required": ["type", "name"]
+ "required": [
+ "type",
+ "name"
+ ]
},
"SubtaskPartInput": {
"type": "object",
@@ -11505,13 +12486,21 @@
"type": "string"
}
},
- "required": ["providerID", "modelID"]
+ "required": [
+ "providerID",
+ "modelID"
+ ]
},
"command": {
"type": "string"
}
},
- "required": ["type", "prompt", "description", "agent"]
+ "required": [
+ "type",
+ "prompt",
+ "description",
+ "agent"
+ ]
},
"ProviderAuthMethod": {
"type": "object",
@@ -11532,7 +12521,10 @@
"type": "string"
}
},
- "required": ["type", "label"]
+ "required": [
+ "type",
+ "label"
+ ]
},
"ProviderAuthAuthorization": {
"type": "object",
@@ -11556,7 +12548,11 @@
"type": "string"
}
},
- "required": ["url", "method", "instructions"]
+ "required": [
+ "url",
+ "method",
+ "instructions"
+ ]
},
"Symbol": {
"type": "object",
@@ -11577,10 +12573,17 @@
"$ref": "#/components/schemas/Range"
}
},
- "required": ["uri", "range"]
+ "required": [
+ "uri",
+ "range"
+ ]
}
},
- "required": ["name", "kind", "location"]
+ "required": [
+ "name",
+ "kind",
+ "location"
+ ]
},
"FileNode": {
"type": "object",
@@ -11596,20 +12599,32 @@
},
"type": {
"type": "string",
- "enum": ["file", "directory"]
+ "enum": [
+ "file",
+ "directory"
+ ]
},
"ignored": {
"type": "boolean"
}
},
- "required": ["name", "path", "absolute", "type", "ignored"]
+ "required": [
+ "name",
+ "path",
+ "absolute",
+ "type",
+ "ignored"
+ ]
},
"FileContent": {
"type": "object",
"properties": {
"type": {
"type": "string",
- "enum": ["text", "binary"]
+ "enum": [
+ "text",
+ "binary"
+ ]
},
"content": {
"type": "string"
@@ -11656,14 +12671,24 @@
}
}
},
- "required": ["oldStart", "oldLines", "newStart", "newLines", "lines"]
+ "required": [
+ "oldStart",
+ "oldLines",
+ "newStart",
+ "newLines",
+ "lines"
+ ]
}
},
"index": {
"type": "string"
}
},
- "required": ["oldFileName", "newFileName", "hunks"]
+ "required": [
+ "oldFileName",
+ "newFileName",
+ "hunks"
+ ]
},
"encoding": {
"type": "string",
@@ -11673,7 +12698,10 @@
"type": "string"
}
},
- "required": ["type", "content"]
+ "required": [
+ "type",
+ "content"
+ ]
},
"File": {
"type": "object",
@@ -11693,10 +12721,19 @@
},
"status": {
"type": "string",
- "enum": ["added", "deleted", "modified"]
+ "enum": [
+ "added",
+ "deleted",
+ "modified"
+ ]
}
},
- "required": ["path", "added", "removed", "status"]
+ "required": [
+ "path",
+ "added",
+ "removed",
+ "status"
+ ]
},
"MCPStatusConnected": {
"type": "object",
@@ -11706,7 +12743,9 @@
"const": "connected"
}
},
- "required": ["status"]
+ "required": [
+ "status"
+ ]
},
"MCPStatusDisabled": {
"type": "object",
@@ -11716,7 +12755,9 @@
"const": "disabled"
}
},
- "required": ["status"]
+ "required": [
+ "status"
+ ]
},
"MCPStatusFailed": {
"type": "object",
@@ -11729,7 +12770,10 @@
"type": "string"
}
},
- "required": ["status", "error"]
+ "required": [
+ "status",
+ "error"
+ ]
},
"MCPStatusNeedsAuth": {
"type": "object",
@@ -11739,7 +12783,9 @@
"const": "needs_auth"
}
},
- "required": ["status"]
+ "required": [
+ "status"
+ ]
},
"MCPStatusNeedsClientRegistration": {
"type": "object",
@@ -11752,7 +12798,10 @@
"type": "string"
}
},
- "required": ["status", "error"]
+ "required": [
+ "status",
+ "error"
+ ]
},
"MCPStatus": {
"anyOf": [
@@ -11792,7 +12841,13 @@
"type": "string"
}
},
- "required": ["home", "state", "config", "worktree", "directory"]
+ "required": [
+ "home",
+ "state",
+ "config",
+ "worktree",
+ "directory"
+ ]
},
"VcsInfo": {
"type": "object",
@@ -11801,7 +12856,9 @@
"type": "string"
}
},
- "required": ["branch"]
+ "required": [
+ "branch"
+ ]
},
"Command": {
"type": "object",
@@ -11820,7 +12877,11 @@
},
"source": {
"type": "string",
- "enum": ["command", "mcp", "skill"]
+ "enum": [
+ "command",
+ "mcp",
+ "skill"
+ ]
},
"template": {
"anyOf": [
@@ -11842,7 +12903,11 @@
}
}
},
- "required": ["name", "template", "hints"]
+ "required": [
+ "name",
+ "template",
+ "hints"
+ ]
},
"Agent": {
"type": "object",
@@ -11855,7 +12920,11 @@
},
"mode": {
"type": "string",
- "enum": ["subagent", "primary", "all"]
+ "enum": [
+ "subagent",
+ "primary",
+ "all"
+ ]
},
"native": {
"type": "boolean"
@@ -11885,7 +12954,10 @@
"type": "string"
}
},
- "required": ["modelID", "providerID"]
+ "required": [
+ "modelID",
+ "providerID"
+ ]
},
"variant": {
"type": "string"
@@ -11906,7 +12978,12 @@
"maximum": 9007199254740991
}
},
- "required": ["name", "mode", "permission", "options"]
+ "required": [
+ "name",
+ "mode",
+ "permission",
+ "options"
+ ]
},
"LSPStatus": {
"type": "object",
@@ -11933,7 +13010,12 @@
]
}
},
- "required": ["id", "name", "root", "status"]
+ "required": [
+ "id",
+ "name",
+ "root",
+ "status"
+ ]
},
"FormatterStatus": {
"type": "object",
@@ -11951,8 +13033,12 @@
"type": "boolean"
}
},
- "required": ["name", "extensions", "enabled"]
+ "required": [
+ "name",
+ "extensions",
+ "enabled"
+ ]
}
}
}
-}
+} \ No newline at end of file