mirror of
https://github.com/CherryHQ/cherry-studio.git
synced 2026-07-03 12:27:41 +08:00
### What this PR does Before this PR: Cherry Studio only supports `claude-code` as an agent type. Agents have no autonomous scheduling, no IM channel integration, and no soul/personality system. After this PR: Introduces **CherryClaw** — a new autonomous agent type with: - **Soul-driven personality**: Markdown-based soul files with mtime-cached reading - **Task-based scheduler**: Poll-loop scheduler with drift-resistant interval computation, tasks as first-class DB entities (nanoclaw-inspired) - **Internal claw MCP server**: `cron` tool (add/list/remove) auto-injected into CherryClaw sessions for autonomous task management - **Channel abstraction layer**: Pluggable adapter pattern with Telegram as the first implementation (grammY, long polling, streaming drafts, typing indicators) - **Headless message persistence**: Channel and scheduler messages now persist to the agent SQLite DB - **Basic sandbox mode**: PreToolUse hook path enforcement + OS-level sandbox toggle - **Full UI**: Agent creation modal with type selector, settings tabs (soul, tasks, channels, advanced), task management CRUD, channel catalog with inline config - **53 unit tests** across 8 test files covering all new services <!-- Fixes # --> ### Why we need it and why it was done in this way CherryClaw enables Cherry Studio agents to operate autonomously — executing scheduled tasks and responding to IM messages without user interaction. This is the foundation for "always-on" AI assistants. The following tradeoffs were made: - **Poll-loop scheduler over timer-based**: DB is the source of truth; no timer state to restore on restart. Simpler, more robust at the cost of up to 60s latency. - **AgentServiceRegistry pattern**: Replaced hardcoded `ClaudeCodeService` in `SessionMessageService` with a registry mapping `AgentType` → service. Extensible for future agent types. - **Internal MCP server for cron**: Rather than extending the SDK's tool system, the `cron` tool is served as a standard MCP server at `/v1/claw/:agentId/claw-mcp`. This lets the agent discover and use it naturally. - **Channel abstraction over direct Telegram integration**: `ChannelAdapter` + factory registration enables future Discord/Slack adapters without touching core routing logic. - **Basic sandbox (not security boundary)**: PreToolUse hook + OS sandbox provides best-effort restriction for well-behaved agents. Known bypass vectors documented; hardening deferred. The following alternatives were considered: - cron-based OS scheduling (rejected: harder to manage lifecycle, no DB integration) - Direct Telegram bot API calls (rejected: grammY provides typed API, connection management, and middleware) - Modifying SDK builtin tools (rejected: internal MCP server is cleaner separation) ### Breaking changes None. This is a new agent type (`cherry-claw`) alongside the existing `claude-code` type. No existing behavior is modified. ### Special notes for your reviewer - **New DB migration**: `0003_wise_meltdown.sql` adds `scheduled_tasks` and `task_run_logs` tables (agents DB only, not IndexedDB) - **New dependencies**: `cron-parser` ^5.5.0, `grammy` ^1.41 - **Placeholder avatar**: `cherry-claw.png` is currently a copy of `claude.png` — needs a proper distinct image - **74 files changed, ~7400 lines added** — large PR, recommend reviewing by phase (type system → backend services → MCP → channels → UI → tests) - **Sandbox is basic only**: The PreToolUse path checking has known bypasses (relative paths, variable expansion). Documented in handoff.md. Hardening is follow-up work. - The `handoff.md` file in the repo root contains full architectural context and decisions ### Checklist - [x] PR: The PR description is expressive enough and will help future contributors - [x] Code: [Write code that humans can understand](https://en.wikiquote.org/wiki/Martin_Fowler#code-for-humans) and [Keep it simple](https://en.wikipedia.org/wiki/KISS_principle) - [x] Refactor: You have [left the code cleaner than you found it (Boy Scout Rule)](https://learning.oreilly.com/library/view/97-things-every/9780596809515/ch08.html) - [ ] Upgrade: Impact of this change on upgrade flows was considered and addressed if required - [ ] Documentation: A [user-guide update](https://docs.cherry-ai.com) was considered and is present (link) or not required. Check this only when the PR introduces or changes a user-facing feature or behavior. - [ ] Self-review: I have reviewed my own code (e.g., via [`/gh-pr-review`](/.claude/skills/gh-pr-review/SKILL.md), `gh pr diff`, or GitHub UI) before requesting review from others ### Release note ```release-note New CherryClaw agent type: autonomous agents with soul-driven personality, task-based scheduling (cron/interval/one-time), internal cron MCP tool for self-managed tasks, Telegram channel integration with streaming responses, and basic sandbox mode for filesystem restriction. ``` --------- Signed-off-by: Vaayne <liu.vaayne@gmail.com> Signed-off-by: suyao <sy20010504@gmail.com> Signed-off-by: Siin Xu <31815270+SiinXu@users.noreply.github.com> Signed-off-by: zhangjiadi225 <625013594@qq.com> Signed-off-by: greycheng255 <greycheng255@gmail.com> Co-authored-by: kangfenmao <kangfenmao@qq.com> Co-authored-by: suyao <sy20010504@gmail.com> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> Co-authored-by: Siin Xu <31815270+SiinXu@users.noreply.github.com> Co-authored-by: fullex <106392080+0xfullex@users.noreply.github.com> Co-authored-by: zhangjiadi225 <625013594@qq.com>
724 lines
19 KiB
JSON
724 lines
19 KiB
JSON
{
|
|
"version": "6",
|
|
"dialect": "sqlite",
|
|
"id": "801df828-be44-457d-96b7-e80944b37b37",
|
|
"prevId": "2bde7356-6a69-4445-b163-3299b4b4972f",
|
|
"tables": {
|
|
"agents": {
|
|
"name": "agents",
|
|
"columns": {
|
|
"id": {
|
|
"name": "id",
|
|
"type": "text",
|
|
"primaryKey": true,
|
|
"notNull": true,
|
|
"autoincrement": false
|
|
},
|
|
"type": {
|
|
"name": "type",
|
|
"type": "text",
|
|
"primaryKey": false,
|
|
"notNull": true,
|
|
"autoincrement": false
|
|
},
|
|
"name": {
|
|
"name": "name",
|
|
"type": "text",
|
|
"primaryKey": false,
|
|
"notNull": true,
|
|
"autoincrement": false
|
|
},
|
|
"description": {
|
|
"name": "description",
|
|
"type": "text",
|
|
"primaryKey": false,
|
|
"notNull": false,
|
|
"autoincrement": false
|
|
},
|
|
"accessible_paths": {
|
|
"name": "accessible_paths",
|
|
"type": "text",
|
|
"primaryKey": false,
|
|
"notNull": false,
|
|
"autoincrement": false
|
|
},
|
|
"instructions": {
|
|
"name": "instructions",
|
|
"type": "text",
|
|
"primaryKey": false,
|
|
"notNull": false,
|
|
"autoincrement": false
|
|
},
|
|
"model": {
|
|
"name": "model",
|
|
"type": "text",
|
|
"primaryKey": false,
|
|
"notNull": true,
|
|
"autoincrement": false
|
|
},
|
|
"plan_model": {
|
|
"name": "plan_model",
|
|
"type": "text",
|
|
"primaryKey": false,
|
|
"notNull": false,
|
|
"autoincrement": false
|
|
},
|
|
"small_model": {
|
|
"name": "small_model",
|
|
"type": "text",
|
|
"primaryKey": false,
|
|
"notNull": false,
|
|
"autoincrement": false
|
|
},
|
|
"mcps": {
|
|
"name": "mcps",
|
|
"type": "text",
|
|
"primaryKey": false,
|
|
"notNull": false,
|
|
"autoincrement": false
|
|
},
|
|
"allowed_tools": {
|
|
"name": "allowed_tools",
|
|
"type": "text",
|
|
"primaryKey": false,
|
|
"notNull": false,
|
|
"autoincrement": false
|
|
},
|
|
"configuration": {
|
|
"name": "configuration",
|
|
"type": "text",
|
|
"primaryKey": false,
|
|
"notNull": false,
|
|
"autoincrement": false
|
|
},
|
|
"sort_order": {
|
|
"name": "sort_order",
|
|
"type": "integer",
|
|
"primaryKey": false,
|
|
"notNull": true,
|
|
"autoincrement": false,
|
|
"default": 0
|
|
},
|
|
"created_at": {
|
|
"name": "created_at",
|
|
"type": "text",
|
|
"primaryKey": false,
|
|
"notNull": true,
|
|
"autoincrement": false
|
|
},
|
|
"updated_at": {
|
|
"name": "updated_at",
|
|
"type": "text",
|
|
"primaryKey": false,
|
|
"notNull": true,
|
|
"autoincrement": false
|
|
}
|
|
},
|
|
"indexes": {},
|
|
"foreignKeys": {},
|
|
"compositePrimaryKeys": {},
|
|
"uniqueConstraints": {},
|
|
"checkConstraints": {}
|
|
},
|
|
"channel_task_subscriptions": {
|
|
"name": "channel_task_subscriptions",
|
|
"columns": {
|
|
"channel_id": {
|
|
"name": "channel_id",
|
|
"type": "text",
|
|
"primaryKey": false,
|
|
"notNull": true,
|
|
"autoincrement": false
|
|
},
|
|
"task_id": {
|
|
"name": "task_id",
|
|
"type": "text",
|
|
"primaryKey": false,
|
|
"notNull": true,
|
|
"autoincrement": false
|
|
}
|
|
},
|
|
"indexes": {
|
|
"cts_channel_id_idx": {
|
|
"name": "cts_channel_id_idx",
|
|
"columns": ["channel_id"],
|
|
"isUnique": false
|
|
},
|
|
"cts_task_id_idx": {
|
|
"name": "cts_task_id_idx",
|
|
"columns": ["task_id"],
|
|
"isUnique": false
|
|
}
|
|
},
|
|
"foreignKeys": {
|
|
"channel_task_subscriptions_channel_id_channels_id_fk": {
|
|
"name": "channel_task_subscriptions_channel_id_channels_id_fk",
|
|
"tableFrom": "channel_task_subscriptions",
|
|
"tableTo": "channels",
|
|
"columnsFrom": ["channel_id"],
|
|
"columnsTo": ["id"],
|
|
"onDelete": "cascade",
|
|
"onUpdate": "no action"
|
|
},
|
|
"channel_task_subscriptions_task_id_scheduled_tasks_id_fk": {
|
|
"name": "channel_task_subscriptions_task_id_scheduled_tasks_id_fk",
|
|
"tableFrom": "channel_task_subscriptions",
|
|
"tableTo": "scheduled_tasks",
|
|
"columnsFrom": ["task_id"],
|
|
"columnsTo": ["id"],
|
|
"onDelete": "cascade",
|
|
"onUpdate": "no action"
|
|
}
|
|
},
|
|
"compositePrimaryKeys": {
|
|
"channel_task_subscriptions_channel_id_task_id_pk": {
|
|
"columns": ["channel_id", "task_id"],
|
|
"name": "channel_task_subscriptions_channel_id_task_id_pk"
|
|
}
|
|
},
|
|
"uniqueConstraints": {},
|
|
"checkConstraints": {}
|
|
},
|
|
"channels": {
|
|
"name": "channels",
|
|
"columns": {
|
|
"id": {
|
|
"name": "id",
|
|
"type": "text",
|
|
"primaryKey": true,
|
|
"notNull": true,
|
|
"autoincrement": false
|
|
},
|
|
"type": {
|
|
"name": "type",
|
|
"type": "text",
|
|
"primaryKey": false,
|
|
"notNull": true,
|
|
"autoincrement": false
|
|
},
|
|
"name": {
|
|
"name": "name",
|
|
"type": "text",
|
|
"primaryKey": false,
|
|
"notNull": true,
|
|
"autoincrement": false
|
|
},
|
|
"agent_id": {
|
|
"name": "agent_id",
|
|
"type": "text",
|
|
"primaryKey": false,
|
|
"notNull": false,
|
|
"autoincrement": false
|
|
},
|
|
"session_id": {
|
|
"name": "session_id",
|
|
"type": "text",
|
|
"primaryKey": false,
|
|
"notNull": false,
|
|
"autoincrement": false
|
|
},
|
|
"config": {
|
|
"name": "config",
|
|
"type": "text",
|
|
"primaryKey": false,
|
|
"notNull": true,
|
|
"autoincrement": false
|
|
},
|
|
"is_active": {
|
|
"name": "is_active",
|
|
"type": "integer",
|
|
"primaryKey": false,
|
|
"notNull": true,
|
|
"autoincrement": false,
|
|
"default": true
|
|
},
|
|
"active_chat_ids": {
|
|
"name": "active_chat_ids",
|
|
"type": "text",
|
|
"primaryKey": false,
|
|
"notNull": false,
|
|
"autoincrement": false,
|
|
"default": "'[]'"
|
|
},
|
|
"permission_mode": {
|
|
"name": "permission_mode",
|
|
"type": "text",
|
|
"primaryKey": false,
|
|
"notNull": false,
|
|
"autoincrement": false
|
|
},
|
|
"created_at": {
|
|
"name": "created_at",
|
|
"type": "integer",
|
|
"primaryKey": false,
|
|
"notNull": false,
|
|
"autoincrement": false
|
|
},
|
|
"updated_at": {
|
|
"name": "updated_at",
|
|
"type": "integer",
|
|
"primaryKey": false,
|
|
"notNull": false,
|
|
"autoincrement": false
|
|
}
|
|
},
|
|
"indexes": {
|
|
"channels_agent_id_idx": {
|
|
"name": "channels_agent_id_idx",
|
|
"columns": ["agent_id"],
|
|
"isUnique": false
|
|
},
|
|
"channels_type_idx": {
|
|
"name": "channels_type_idx",
|
|
"columns": ["type"],
|
|
"isUnique": false
|
|
},
|
|
"channels_session_id_idx": {
|
|
"name": "channels_session_id_idx",
|
|
"columns": ["session_id"],
|
|
"isUnique": false
|
|
}
|
|
},
|
|
"foreignKeys": {
|
|
"channels_agent_id_agents_id_fk": {
|
|
"name": "channels_agent_id_agents_id_fk",
|
|
"tableFrom": "channels",
|
|
"tableTo": "agents",
|
|
"columnsFrom": ["agent_id"],
|
|
"columnsTo": ["id"],
|
|
"onDelete": "set null",
|
|
"onUpdate": "no action"
|
|
},
|
|
"channels_session_id_sessions_id_fk": {
|
|
"name": "channels_session_id_sessions_id_fk",
|
|
"tableFrom": "channels",
|
|
"tableTo": "sessions",
|
|
"columnsFrom": ["session_id"],
|
|
"columnsTo": ["id"],
|
|
"onDelete": "set null",
|
|
"onUpdate": "no action"
|
|
}
|
|
},
|
|
"compositePrimaryKeys": {},
|
|
"uniqueConstraints": {},
|
|
"checkConstraints": {
|
|
"channels_type_check": {
|
|
"name": "channels_type_check",
|
|
"value": "\"channels\".\"type\" IN ('telegram', 'feishu', 'qq', 'wechat', 'discord', 'slack')"
|
|
},
|
|
"channels_permission_mode_check": {
|
|
"name": "channels_permission_mode_check",
|
|
"value": "\"channels\".\"permission_mode\" IS NULL OR \"channels\".\"permission_mode\" IN ('default', 'acceptEdits', 'bypassPermissions', 'plan')"
|
|
}
|
|
}
|
|
},
|
|
"session_messages": {
|
|
"name": "session_messages",
|
|
"columns": {
|
|
"id": {
|
|
"name": "id",
|
|
"type": "integer",
|
|
"primaryKey": true,
|
|
"notNull": true,
|
|
"autoincrement": true
|
|
},
|
|
"session_id": {
|
|
"name": "session_id",
|
|
"type": "text",
|
|
"primaryKey": false,
|
|
"notNull": true,
|
|
"autoincrement": false
|
|
},
|
|
"role": {
|
|
"name": "role",
|
|
"type": "text",
|
|
"primaryKey": false,
|
|
"notNull": true,
|
|
"autoincrement": false
|
|
},
|
|
"content": {
|
|
"name": "content",
|
|
"type": "text",
|
|
"primaryKey": false,
|
|
"notNull": true,
|
|
"autoincrement": false
|
|
},
|
|
"agent_session_id": {
|
|
"name": "agent_session_id",
|
|
"type": "text",
|
|
"primaryKey": false,
|
|
"notNull": false,
|
|
"autoincrement": false,
|
|
"default": "''"
|
|
},
|
|
"metadata": {
|
|
"name": "metadata",
|
|
"type": "text",
|
|
"primaryKey": false,
|
|
"notNull": false,
|
|
"autoincrement": false
|
|
},
|
|
"created_at": {
|
|
"name": "created_at",
|
|
"type": "text",
|
|
"primaryKey": false,
|
|
"notNull": true,
|
|
"autoincrement": false
|
|
},
|
|
"updated_at": {
|
|
"name": "updated_at",
|
|
"type": "text",
|
|
"primaryKey": false,
|
|
"notNull": true,
|
|
"autoincrement": false
|
|
}
|
|
},
|
|
"indexes": {},
|
|
"foreignKeys": {},
|
|
"compositePrimaryKeys": {},
|
|
"uniqueConstraints": {},
|
|
"checkConstraints": {}
|
|
},
|
|
"migrations": {
|
|
"name": "migrations",
|
|
"columns": {
|
|
"version": {
|
|
"name": "version",
|
|
"type": "integer",
|
|
"primaryKey": true,
|
|
"notNull": true,
|
|
"autoincrement": false
|
|
},
|
|
"tag": {
|
|
"name": "tag",
|
|
"type": "text",
|
|
"primaryKey": false,
|
|
"notNull": true,
|
|
"autoincrement": false
|
|
},
|
|
"executed_at": {
|
|
"name": "executed_at",
|
|
"type": "integer",
|
|
"primaryKey": false,
|
|
"notNull": true,
|
|
"autoincrement": false
|
|
}
|
|
},
|
|
"indexes": {},
|
|
"foreignKeys": {},
|
|
"compositePrimaryKeys": {},
|
|
"uniqueConstraints": {},
|
|
"checkConstraints": {}
|
|
},
|
|
"sessions": {
|
|
"name": "sessions",
|
|
"columns": {
|
|
"id": {
|
|
"name": "id",
|
|
"type": "text",
|
|
"primaryKey": true,
|
|
"notNull": true,
|
|
"autoincrement": false
|
|
},
|
|
"agent_type": {
|
|
"name": "agent_type",
|
|
"type": "text",
|
|
"primaryKey": false,
|
|
"notNull": true,
|
|
"autoincrement": false
|
|
},
|
|
"agent_id": {
|
|
"name": "agent_id",
|
|
"type": "text",
|
|
"primaryKey": false,
|
|
"notNull": true,
|
|
"autoincrement": false
|
|
},
|
|
"name": {
|
|
"name": "name",
|
|
"type": "text",
|
|
"primaryKey": false,
|
|
"notNull": true,
|
|
"autoincrement": false
|
|
},
|
|
"description": {
|
|
"name": "description",
|
|
"type": "text",
|
|
"primaryKey": false,
|
|
"notNull": false,
|
|
"autoincrement": false
|
|
},
|
|
"accessible_paths": {
|
|
"name": "accessible_paths",
|
|
"type": "text",
|
|
"primaryKey": false,
|
|
"notNull": false,
|
|
"autoincrement": false
|
|
},
|
|
"instructions": {
|
|
"name": "instructions",
|
|
"type": "text",
|
|
"primaryKey": false,
|
|
"notNull": false,
|
|
"autoincrement": false
|
|
},
|
|
"model": {
|
|
"name": "model",
|
|
"type": "text",
|
|
"primaryKey": false,
|
|
"notNull": true,
|
|
"autoincrement": false
|
|
},
|
|
"plan_model": {
|
|
"name": "plan_model",
|
|
"type": "text",
|
|
"primaryKey": false,
|
|
"notNull": false,
|
|
"autoincrement": false
|
|
},
|
|
"small_model": {
|
|
"name": "small_model",
|
|
"type": "text",
|
|
"primaryKey": false,
|
|
"notNull": false,
|
|
"autoincrement": false
|
|
},
|
|
"mcps": {
|
|
"name": "mcps",
|
|
"type": "text",
|
|
"primaryKey": false,
|
|
"notNull": false,
|
|
"autoincrement": false
|
|
},
|
|
"allowed_tools": {
|
|
"name": "allowed_tools",
|
|
"type": "text",
|
|
"primaryKey": false,
|
|
"notNull": false,
|
|
"autoincrement": false
|
|
},
|
|
"slash_commands": {
|
|
"name": "slash_commands",
|
|
"type": "text",
|
|
"primaryKey": false,
|
|
"notNull": false,
|
|
"autoincrement": false
|
|
},
|
|
"configuration": {
|
|
"name": "configuration",
|
|
"type": "text",
|
|
"primaryKey": false,
|
|
"notNull": false,
|
|
"autoincrement": false
|
|
},
|
|
"sort_order": {
|
|
"name": "sort_order",
|
|
"type": "integer",
|
|
"primaryKey": false,
|
|
"notNull": true,
|
|
"autoincrement": false,
|
|
"default": 0
|
|
},
|
|
"created_at": {
|
|
"name": "created_at",
|
|
"type": "text",
|
|
"primaryKey": false,
|
|
"notNull": true,
|
|
"autoincrement": false
|
|
},
|
|
"updated_at": {
|
|
"name": "updated_at",
|
|
"type": "text",
|
|
"primaryKey": false,
|
|
"notNull": true,
|
|
"autoincrement": false
|
|
}
|
|
},
|
|
"indexes": {},
|
|
"foreignKeys": {},
|
|
"compositePrimaryKeys": {},
|
|
"uniqueConstraints": {},
|
|
"checkConstraints": {}
|
|
},
|
|
"scheduled_tasks": {
|
|
"name": "scheduled_tasks",
|
|
"columns": {
|
|
"id": {
|
|
"name": "id",
|
|
"type": "text",
|
|
"primaryKey": true,
|
|
"notNull": true,
|
|
"autoincrement": false
|
|
},
|
|
"agent_id": {
|
|
"name": "agent_id",
|
|
"type": "text",
|
|
"primaryKey": false,
|
|
"notNull": true,
|
|
"autoincrement": false
|
|
},
|
|
"name": {
|
|
"name": "name",
|
|
"type": "text",
|
|
"primaryKey": false,
|
|
"notNull": true,
|
|
"autoincrement": false
|
|
},
|
|
"prompt": {
|
|
"name": "prompt",
|
|
"type": "text",
|
|
"primaryKey": false,
|
|
"notNull": true,
|
|
"autoincrement": false
|
|
},
|
|
"schedule_type": {
|
|
"name": "schedule_type",
|
|
"type": "text",
|
|
"primaryKey": false,
|
|
"notNull": true,
|
|
"autoincrement": false
|
|
},
|
|
"schedule_value": {
|
|
"name": "schedule_value",
|
|
"type": "text",
|
|
"primaryKey": false,
|
|
"notNull": true,
|
|
"autoincrement": false
|
|
},
|
|
"timeout_minutes": {
|
|
"name": "timeout_minutes",
|
|
"type": "integer",
|
|
"primaryKey": false,
|
|
"notNull": true,
|
|
"autoincrement": false,
|
|
"default": 2
|
|
},
|
|
"next_run": {
|
|
"name": "next_run",
|
|
"type": "text",
|
|
"primaryKey": false,
|
|
"notNull": false,
|
|
"autoincrement": false
|
|
},
|
|
"last_run": {
|
|
"name": "last_run",
|
|
"type": "text",
|
|
"primaryKey": false,
|
|
"notNull": false,
|
|
"autoincrement": false
|
|
},
|
|
"last_result": {
|
|
"name": "last_result",
|
|
"type": "text",
|
|
"primaryKey": false,
|
|
"notNull": false,
|
|
"autoincrement": false
|
|
},
|
|
"status": {
|
|
"name": "status",
|
|
"type": "text",
|
|
"primaryKey": false,
|
|
"notNull": true,
|
|
"autoincrement": false,
|
|
"default": "'active'"
|
|
},
|
|
"created_at": {
|
|
"name": "created_at",
|
|
"type": "text",
|
|
"primaryKey": false,
|
|
"notNull": true,
|
|
"autoincrement": false
|
|
},
|
|
"updated_at": {
|
|
"name": "updated_at",
|
|
"type": "text",
|
|
"primaryKey": false,
|
|
"notNull": true,
|
|
"autoincrement": false
|
|
}
|
|
},
|
|
"indexes": {},
|
|
"foreignKeys": {},
|
|
"compositePrimaryKeys": {},
|
|
"uniqueConstraints": {},
|
|
"checkConstraints": {}
|
|
},
|
|
"task_run_logs": {
|
|
"name": "task_run_logs",
|
|
"columns": {
|
|
"id": {
|
|
"name": "id",
|
|
"type": "integer",
|
|
"primaryKey": true,
|
|
"notNull": true,
|
|
"autoincrement": true
|
|
},
|
|
"task_id": {
|
|
"name": "task_id",
|
|
"type": "text",
|
|
"primaryKey": false,
|
|
"notNull": true,
|
|
"autoincrement": false
|
|
},
|
|
"session_id": {
|
|
"name": "session_id",
|
|
"type": "text",
|
|
"primaryKey": false,
|
|
"notNull": false,
|
|
"autoincrement": false
|
|
},
|
|
"run_at": {
|
|
"name": "run_at",
|
|
"type": "text",
|
|
"primaryKey": false,
|
|
"notNull": true,
|
|
"autoincrement": false
|
|
},
|
|
"duration_ms": {
|
|
"name": "duration_ms",
|
|
"type": "integer",
|
|
"primaryKey": false,
|
|
"notNull": true,
|
|
"autoincrement": false
|
|
},
|
|
"status": {
|
|
"name": "status",
|
|
"type": "text",
|
|
"primaryKey": false,
|
|
"notNull": true,
|
|
"autoincrement": false
|
|
},
|
|
"result": {
|
|
"name": "result",
|
|
"type": "text",
|
|
"primaryKey": false,
|
|
"notNull": false,
|
|
"autoincrement": false
|
|
},
|
|
"error": {
|
|
"name": "error",
|
|
"type": "text",
|
|
"primaryKey": false,
|
|
"notNull": false,
|
|
"autoincrement": false
|
|
}
|
|
},
|
|
"indexes": {},
|
|
"foreignKeys": {},
|
|
"compositePrimaryKeys": {},
|
|
"uniqueConstraints": {},
|
|
"checkConstraints": {}
|
|
}
|
|
},
|
|
"views": {},
|
|
"enums": {},
|
|
"_meta": {
|
|
"schemas": {},
|
|
"tables": {},
|
|
"columns": {}
|
|
},
|
|
"internal": {
|
|
"indexes": {}
|
|
}
|
|
}
|