bonecode 1.0.0 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +64 -50
- package/bone/output/agent/.dockerignore +7 -7
- package/bone/output/agent/.env.example +36 -36
- package/bone/output/agent/.github/workflows/ci.yaml +58 -58
- package/bone/output/agent/AgentDomain.bone.map +349 -349
- package/bone/output/agent/AgentDomain.postman_collection.json +957 -957
- package/bone/output/agent/Dockerfile +22 -22
- package/bone/output/agent/README.md +47 -47
- package/bone/output/agent/admin/index.html +739 -739
- package/bone/output/agent/docker-compose.yaml +22 -22
- package/bone/output/agent/k8s/deployment.yaml +75 -75
- package/bone/output/agent/migrations/agent.sql +36 -36
- package/bone/output/agent/migrations/agent_instance.sql +36 -36
- package/bone/output/agent/migrations/audit_log.sql +18 -18
- package/bone/output/agent/migrations/build_step.sql +34 -34
- package/bone/output/agent/migrations/event_outbox.sql +31 -31
- package/bone/output/agent/migrations/plan.sql +30 -30
- package/bone/output/agent/migrations/task.sql +30 -30
- package/bone/output/agent/migrations/tool_call.sql +33 -33
- package/bone/output/agent/openapi.yaml +1116 -1116
- package/bone/output/agent/package.json +35 -35
- package/bone/output/agent/schema.graphql +233 -233
- package/bone/output/agent/sdk/client.ts +231 -231
- package/bone/output/agent/src/algorithms.ts +2 -2
- package/bone/output/agent/src/audit.ts +44 -44
- package/bone/output/agent/src/auth.ts +57 -57
- package/bone/output/agent/src/cron.ts +12 -12
- package/bone/output/agent/src/db.ts +31 -31
- package/bone/output/agent/src/debug.ts +66 -66
- package/bone/output/agent/src/events.ts +243 -243
- package/bone/output/agent/src/extensions.ts +54 -54
- package/bone/output/agent/src/failure_rules.ts +322 -322
- package/bone/output/agent/src/flows.ts +168 -168
- package/bone/output/agent/src/health.ts +43 -43
- package/bone/output/agent/src/index.ts +99 -99
- package/bone/output/agent/src/logger.ts +69 -66
- package/bone/output/agent/src/metrics.ts +75 -75
- package/bone/output/agent/src/migrate.ts +351 -351
- package/bone/output/agent/src/migration_diff.ts +108 -108
- package/bone/output/agent/src/notify.ts +125 -125
- package/bone/output/agent/src/routes/plan.ts +91 -91
- package/bone/output/agent/src/routes/task.ts +105 -105
- package/bone/output/agent/src/routes/tool_call.ts +166 -166
- package/bone/output/agent/src/schemas.ts +384 -384
- package/bone/output/agent/src/state_machines/agent_instance.ts +24 -24
- package/bone/output/agent/src/state_machines/build_step.ts +22 -22
- package/bone/output/agent/src/state_machines/plan.ts +22 -22
- package/bone/output/agent/src/state_machines/task.ts +22 -22
- package/bone/output/agent/src/state_machines/tool_call.ts +22 -22
- package/bone/output/agent/src/tests.ts +361 -361
- package/bone/output/agent/src/websocket.ts +200 -200
- package/bone/output/agent/tsconfig.json +24 -24
- package/bone/output/rag/.dockerignore +7 -7
- package/bone/output/rag/.env.example +36 -36
- package/bone/output/rag/.github/workflows/ci.yaml +58 -58
- package/bone/output/rag/Dockerfile +22 -22
- package/bone/output/rag/RAGDomain.bone.map +286 -286
- package/bone/output/rag/RAGDomain.postman_collection.json +922 -922
- package/bone/output/rag/README.md +47 -47
- package/bone/output/rag/admin/index.html +817 -817
- package/bone/output/rag/docker-compose.yaml +22 -22
- package/bone/output/rag/k8s/deployment.yaml +75 -75
- package/bone/output/rag/migrations/audit_log.sql +18 -18
- package/bone/output/rag/migrations/code_chunk.sql +34 -34
- package/bone/output/rag/migrations/code_file.sql +33 -33
- package/bone/output/rag/migrations/event_outbox.sql +31 -31
- package/bone/output/rag/migrations/indexing_job.sql +33 -33
- package/bone/output/rag/migrations/knowledge_base.sql +35 -35
- package/bone/output/rag/migrations/memory_entry.sql +34 -34
- package/bone/output/rag/openapi.yaml +1097 -1097
- package/bone/output/rag/package.json +35 -35
- package/bone/output/rag/schema.graphql +245 -245
- package/bone/output/rag/sdk/client.ts +234 -234
- package/bone/output/rag/src/algorithms.ts +2 -2
- package/bone/output/rag/src/audit.ts +37 -37
- package/bone/output/rag/src/auth.ts +57 -57
- package/bone/output/rag/src/cron.ts +12 -12
- package/bone/output/rag/src/db.ts +31 -31
- package/bone/output/rag/src/debug.ts +66 -66
- package/bone/output/rag/src/events.ts +243 -243
- package/bone/output/rag/src/extensions.ts +350 -350
- package/bone/output/rag/src/failure_rules.ts +314 -314
- package/bone/output/rag/src/flows.ts +239 -239
- package/bone/output/rag/src/health.ts +43 -43
- package/bone/output/rag/src/index.ts +94 -94
- package/bone/output/rag/src/logger.ts +69 -66
- package/bone/output/rag/src/metrics.ts +75 -75
- package/bone/output/rag/src/migrate.ts +363 -363
- package/bone/output/rag/src/migration_diff.ts +108 -108
- package/bone/output/rag/src/notify.ts +99 -99
- package/bone/output/rag/src/routes/code_chunk.ts +75 -75
- package/bone/output/rag/src/routes/code_file.ts +101 -101
- package/bone/output/rag/src/routes/indexing_job.ts +87 -87
- package/bone/output/rag/src/routes/knowledge_base.ts +230 -230
- package/bone/output/rag/src/routes/memory_entry.ts +87 -87
- package/bone/output/rag/src/schemas.ts +394 -394
- package/bone/output/rag/src/state_machines/code_file.ts +23 -23
- package/bone/output/rag/src/state_machines/indexing_job.ts +22 -22
- package/bone/output/rag/src/state_machines/knowledge_base.ts +23 -23
- package/bone/output/rag/src/state_machines/memory_entry.ts +20 -20
- package/bone/output/rag/src/tests.ts +339 -339
- package/bone/output/rag/tsconfig.json +24 -24
- package/bone/output/session/.dockerignore +7 -7
- package/bone/output/session/.env.example +36 -36
- package/bone/output/session/.github/workflows/ci.yaml +58 -58
- package/bone/output/session/Dockerfile +22 -22
- package/bone/output/session/README.md +47 -47
- package/bone/output/session/SessionDomain.bone.map +349 -349
- package/bone/output/session/SessionDomain.postman_collection.json +957 -957
- package/bone/output/session/admin/index.html +666 -666
- package/bone/output/session/docker-compose.yaml +22 -22
- package/bone/output/session/k8s/deployment.yaml +75 -75
- package/bone/output/session/migrations/audit_log.sql +18 -18
- package/bone/output/session/migrations/event_outbox.sql +31 -31
- package/bone/output/session/migrations/message.sql +31 -31
- package/bone/output/session/migrations/part.sql +28 -28
- package/bone/output/session/migrations/permission.sql +28 -28
- package/bone/output/session/migrations/project.sql +28 -28
- package/bone/output/session/migrations/session.sql +38 -38
- package/bone/output/session/openapi.yaml +1101 -1101
- package/bone/output/session/package.json +35 -35
- package/bone/output/session/schema.graphql +222 -222
- package/bone/output/session/sdk/client.ts +225 -225
- package/bone/output/session/src/algorithms.ts +2 -2
- package/bone/output/session/src/audit.ts +44 -44
- package/bone/output/session/src/auth.ts +57 -57
- package/bone/output/session/src/cron.ts +12 -12
- package/bone/output/session/src/db.ts +31 -31
- package/bone/output/session/src/debug.ts +66 -66
- package/bone/output/session/src/events.ts +270 -270
- package/bone/output/session/src/extensions.ts +215 -215
- package/bone/output/session/src/failure_rules.ts +283 -283
- package/bone/output/session/src/flows.ts +168 -168
- package/bone/output/session/src/health.ts +43 -43
- package/bone/output/session/src/index.ts +99 -99
- package/bone/output/session/src/logger.ts +67 -66
- package/bone/output/session/src/metrics.ts +75 -75
- package/bone/output/session/src/migrate.ts +331 -331
- package/bone/output/session/src/migration_diff.ts +108 -108
- package/bone/output/session/src/notify.ts +112 -112
- package/bone/output/session/src/routes/message.ts +93 -93
- package/bone/output/session/src/routes/part.ts +79 -79
- package/bone/output/session/src/routes/permission.ts +79 -79
- package/bone/output/session/src/routes/project.ts +79 -79
- package/bone/output/session/src/routes/session.ts +294 -294
- package/bone/output/session/src/schemas.ts +357 -357
- package/bone/output/session/src/state_machines/session.ts +23 -23
- package/bone/output/session/src/tests.ts +325 -325
- package/bone/output/session/src/websocket.ts +223 -200
- package/bone/output/session/tsconfig.json +24 -24
- package/bone/output/workspace/.dockerignore +7 -7
- package/bone/output/workspace/.env.example +36 -36
- package/bone/output/workspace/.github/workflows/ci.yaml +58 -58
- package/bone/output/workspace/Dockerfile +22 -22
- package/bone/output/workspace/README.md +45 -45
- package/bone/output/workspace/WorkspaceDomain.bone.map +188 -188
- package/bone/output/workspace/WorkspaceDomain.postman_collection.json +620 -620
- package/bone/output/workspace/admin/index.html +484 -484
- package/bone/output/workspace/docker-compose.yaml +22 -22
- package/bone/output/workspace/k8s/deployment.yaml +75 -75
- package/bone/output/workspace/migrations/audit_log.sql +18 -18
- package/bone/output/workspace/migrations/codebase.sql +34 -34
- package/bone/output/workspace/migrations/event_outbox.sql +31 -31
- package/bone/output/workspace/migrations/snapshot.sql +32 -32
- package/bone/output/workspace/migrations/workspace.sql +33 -33
- package/bone/output/workspace/openapi.yaml +721 -721
- package/bone/output/workspace/package.json +35 -35
- package/bone/output/workspace/schema.graphql +153 -153
- package/bone/output/workspace/sdk/client.ts +155 -155
- package/bone/output/workspace/src/algorithms.ts +2 -2
- package/bone/output/workspace/src/audit.ts +37 -37
- package/bone/output/workspace/src/auth.ts +57 -57
- package/bone/output/workspace/src/cron.ts +12 -12
- package/bone/output/workspace/src/db.ts +31 -31
- package/bone/output/workspace/src/debug.ts +66 -66
- package/bone/output/workspace/src/events.ts +243 -243
- package/bone/output/workspace/src/extensions.ts +44 -44
- package/bone/output/workspace/src/failure_rules.ts +152 -152
- package/bone/output/workspace/src/health.ts +43 -43
- package/bone/output/workspace/src/index.ts +88 -88
- package/bone/output/workspace/src/logger.ts +69 -66
- package/bone/output/workspace/src/metrics.ts +75 -75
- package/bone/output/workspace/src/migrate.ts +219 -219
- package/bone/output/workspace/src/migration_diff.ts +108 -108
- package/bone/output/workspace/src/notify.ts +73 -73
- package/bone/output/workspace/src/routes/codebase.ts +87 -87
- package/bone/output/workspace/src/routes/snapshot.ts +127 -127
- package/bone/output/workspace/src/routes/workspace.ts +190 -190
- package/bone/output/workspace/src/schemas.ts +231 -231
- package/bone/output/workspace/src/state_machines/codebase.ts +21 -21
- package/bone/output/workspace/src/state_machines/snapshot.ts +20 -20
- package/bone/output/workspace/src/state_machines/workspace.ts +21 -21
- package/bone/output/workspace/src/tests.ts +248 -248
- package/bone/output/workspace/tsconfig.json +24 -24
- package/compat/opencode_adapter.ts +94 -17
- package/package.json +15 -2
- package/src/cli.ts +66 -107
- package/src/db_adapter.ts +354 -0
- package/src/engine/account/account.sql.ts +39 -39
- package/src/engine/account/account.ts +456 -456
- package/src/engine/account/repo.ts +166 -166
- package/src/engine/account/schema.ts +99 -99
- package/src/engine/account/url.ts +8 -8
- package/src/engine/acp/README.md +174 -174
- package/src/engine/acp/agent.ts +1968 -1968
- package/src/engine/acp/runtime.ts +22 -22
- package/src/engine/acp/session.ts +122 -122
- package/src/engine/acp/types.ts +24 -24
- package/src/engine/agent/agent.ts +463 -463
- package/src/engine/agent/generate.txt +75 -75
- package/src/engine/agent/prompt/compaction.txt +9 -9
- package/src/engine/agent/prompt/explore.txt +18 -18
- package/src/engine/agent/prompt/scout.txt +36 -36
- package/src/engine/agent/prompt/summary.txt +11 -11
- package/src/engine/agent/prompt/title.txt +44 -44
- package/src/engine/agent/subagent-permissions.ts +34 -34
- package/src/engine/auth/index.ts +96 -96
- package/src/engine/background/background/job.ts +200 -200
- package/src/engine/background/job.ts +200 -200
- package/src/engine/bus/bus-event.ts +45 -45
- package/src/engine/bus/global.ts +22 -22
- package/src/engine/bus/index.ts +203 -203
- package/src/engine/command/command/index.ts +181 -181
- package/src/engine/command/command/template/initialize.txt +66 -66
- package/src/engine/command/command/template/review.txt +101 -101
- package/src/engine/command/index.ts +181 -181
- package/src/engine/command/template/initialize.txt +66 -66
- package/src/engine/command/template/review.txt +101 -101
- package/src/engine/config/agent.ts +172 -172
- package/src/engine/config/attachment.ts +25 -25
- package/src/engine/config/command.ts +62 -62
- package/src/engine/config/config.ts +833 -833
- package/src/engine/config/console-state.ts +14 -14
- package/src/engine/config/entry-name.ts +16 -16
- package/src/engine/config/error.ts +23 -23
- package/src/engine/config/formatter.ts +13 -13
- package/src/engine/config/layout.ts +6 -6
- package/src/engine/config/lsp.ts +43 -43
- package/src/engine/config/managed.ts +71 -71
- package/src/engine/config/markdown.ts +96 -96
- package/src/engine/config/mcp.ts +56 -56
- package/src/engine/config/model-id.ts +5 -5
- package/src/engine/config/parse.ts +79 -79
- package/src/engine/config/paths.ts +45 -45
- package/src/engine/config/permission.ts +58 -58
- package/src/engine/config/plugin.ts +84 -84
- package/src/engine/config/provider.ts +111 -111
- package/src/engine/config/reference.ts +23 -23
- package/src/engine/config/server.ts +19 -19
- package/src/engine/config/skills.ts +14 -14
- package/src/engine/config/variable.ts +90 -90
- package/src/engine/control-plane/adapters/index.ts +41 -41
- package/src/engine/control-plane/adapters/worktree.ts +96 -96
- package/src/engine/control-plane/dev/README.md +19 -19
- package/src/engine/control-plane/dev/debug-workspace-plugin.ts +73 -73
- package/src/engine/control-plane/schema.ts +14 -14
- package/src/engine/control-plane/types.ts +59 -59
- package/src/engine/control-plane/util.ts +39 -39
- package/src/engine/control-plane/workspace-adapter-runtime.ts +51 -51
- package/src/engine/control-plane/workspace-context.ts +26 -26
- package/src/engine/control-plane/workspace.sql.ts +20 -20
- package/src/engine/control-plane/workspace.ts +1072 -1072
- package/src/engine/data-migration.ts +161 -161
- package/src/engine/effect/app-runtime.ts +143 -143
- package/src/engine/effect/bootstrap-runtime.ts +29 -29
- package/src/engine/effect/bridge.ts +84 -84
- package/src/engine/effect/config-service.ts +67 -67
- package/src/engine/effect/instance-ref.ts +11 -11
- package/src/engine/effect/instance-registry.ts +12 -12
- package/src/engine/effect/instance-state.ts +72 -72
- package/src/engine/effect/promise.ts +17 -17
- package/src/engine/effect/run-service.ts +47 -47
- package/src/engine/effect/runner.ts +217 -217
- package/src/engine/effect/runtime-flags.ts +74 -74
- package/src/engine/effect/service-use.ts +38 -38
- package/src/engine/env/index.ts +37 -37
- package/src/engine/event-v2-bridge.ts +89 -89
- package/src/engine/file/file/ignore.ts +81 -81
- package/src/engine/file/file/index.ts +651 -651
- package/src/engine/file/file/protected.ts +59 -59
- package/src/engine/file/file/ripgrep.ts +481 -481
- package/src/engine/file/file/watcher.ts +167 -167
- package/src/engine/file/ignore.ts +81 -81
- package/src/engine/file/index.ts +651 -651
- package/src/engine/file/protected.ts +59 -59
- package/src/engine/file/ripgrep.ts +481 -481
- package/src/engine/file/watcher.ts +167 -167
- package/src/engine/format/format/formatter.ts +404 -404
- package/src/engine/format/format/index.ts +209 -209
- package/src/engine/format/formatter.ts +404 -404
- package/src/engine/format/index.ts +209 -209
- package/src/engine/git/git/index.ts +347 -347
- package/src/engine/git/index.ts +347 -347
- package/src/engine/id/id.ts +80 -80
- package/src/engine/ide/index.ts +70 -70
- package/src/engine/image/image/image.ts +176 -176
- package/src/engine/image/image.ts +176 -176
- package/src/engine/index.ts +251 -251
- package/src/engine/installation/index.ts +327 -327
- package/src/engine/lsp/client.ts +707 -707
- package/src/engine/lsp/diagnostic.ts +29 -29
- package/src/engine/lsp/language.ts +121 -121
- package/src/engine/lsp/launch.ts +21 -21
- package/src/engine/lsp/lsp/client.ts +707 -707
- package/src/engine/lsp/lsp/diagnostic.ts +29 -29
- package/src/engine/lsp/lsp/language.ts +121 -121
- package/src/engine/lsp/lsp/launch.ts +21 -21
- package/src/engine/lsp/lsp/lsp.ts +507 -507
- package/src/engine/lsp/lsp/server.ts +2064 -2064
- package/src/engine/lsp/lsp.ts +507 -507
- package/src/engine/lsp/server.ts +2064 -2064
- package/src/engine/mcp/auth.ts +146 -146
- package/src/engine/mcp/index.ts +958 -958
- package/src/engine/mcp/mcp/auth.ts +146 -146
- package/src/engine/mcp/mcp/index.ts +958 -958
- package/src/engine/mcp/mcp/oauth-callback.ts +232 -232
- package/src/engine/mcp/mcp/oauth-provider.ts +214 -214
- package/src/engine/mcp/oauth-callback.ts +232 -232
- package/src/engine/mcp/oauth-provider.ts +214 -214
- package/src/engine/node.ts +6 -6
- package/src/engine/patch/index.ts +689 -689
- package/src/engine/patch/patch/index.ts +689 -689
- package/src/engine/permission/arity.ts +163 -163
- package/src/engine/permission/evaluate.ts +15 -15
- package/src/engine/permission/index.ts +306 -306
- package/src/engine/permission/permission/arity.ts +163 -163
- package/src/engine/permission/permission/evaluate.ts +15 -15
- package/src/engine/permission/permission/index.ts +306 -306
- package/src/engine/permission/permission/schema.ts +13 -13
- package/src/engine/permission/schema.ts +13 -13
- package/src/engine/plugin/azure.ts +26 -26
- package/src/engine/plugin/cloudflare.ts +76 -76
- package/src/engine/plugin/codex.ts +622 -622
- package/src/engine/plugin/digitalocean.ts +411 -411
- package/src/engine/plugin/github-copilot/copilot.ts +394 -394
- package/src/engine/plugin/github-copilot/models.ts +196 -196
- package/src/engine/plugin/index.ts +295 -295
- package/src/engine/plugin/install.ts +439 -439
- package/src/engine/plugin/loader.ts +216 -216
- package/src/engine/plugin/meta.ts +188 -188
- package/src/engine/plugin/shared.ts +323 -323
- package/src/engine/project/bootstrap-service.ts +9 -9
- package/src/engine/project/bootstrap.ts +75 -75
- package/src/engine/project/instance-context.ts +24 -24
- package/src/engine/project/instance-layer.ts +11 -11
- package/src/engine/project/instance-runtime.ts +16 -16
- package/src/engine/project/instance-store.ts +193 -193
- package/src/engine/project/project.sql.ts +17 -17
- package/src/engine/project/project.ts +537 -537
- package/src/engine/project/schema.ts +13 -13
- package/src/engine/project/vcs.ts +405 -405
- package/src/engine/provider/auth.ts +225 -225
- package/src/engine/provider/error.ts +204 -204
- package/src/engine/provider/model-status.ts +8 -8
- package/src/engine/provider/provider.ts +1843 -1843
- package/src/engine/provider/schema.ts +30 -30
- package/src/engine/provider/transform.ts +1376 -1376
- package/src/engine/pty/index.ts +365 -365
- package/src/engine/pty/input.ts +24 -24
- package/src/engine/pty/pty/index.ts +365 -365
- package/src/engine/pty/pty/input.ts +24 -24
- package/src/engine/pty/pty/pty.bun.ts +26 -26
- package/src/engine/pty/pty/pty.node.ts +27 -27
- package/src/engine/pty/pty/pty.ts +25 -25
- package/src/engine/pty/pty/schema.ts +14 -14
- package/src/engine/pty/pty/ticket.ts +68 -68
- package/src/engine/pty/pty.bun.ts +26 -26
- package/src/engine/pty/pty.node.ts +27 -27
- package/src/engine/pty/pty.ts +25 -25
- package/src/engine/pty/schema.ts +14 -14
- package/src/engine/pty/ticket.ts +68 -68
- package/src/engine/question/index.ts +213 -213
- package/src/engine/question/question/index.ts +213 -213
- package/src/engine/question/question/schema.ts +10 -10
- package/src/engine/question/schema.ts +10 -10
- package/src/engine/reference/reference/reference.ts +241 -241
- package/src/engine/reference/reference/repository-cache.ts +147 -147
- package/src/engine/reference/reference.ts +241 -241
- package/src/engine/reference/repository-cache.ts +147 -147
- package/src/engine/session/compaction.ts +651 -651
- package/src/engine/session/instruction.ts +238 -238
- package/src/engine/session/llm.ts +459 -459
- package/src/engine/session/message-error.ts +14 -14
- package/src/engine/session/message-v2.ts +1202 -1202
- package/src/engine/session/message.ts +146 -146
- package/src/engine/session/overflow.ts +32 -32
- package/src/engine/session/processor.ts +823 -823
- package/src/engine/session/prompt/anthropic.txt +105 -105
- package/src/engine/session/prompt/beast.txt +147 -147
- package/src/engine/session/prompt/build-switch.txt +5 -5
- package/src/engine/session/prompt/codex.txt +79 -79
- package/src/engine/session/prompt/copilot-gpt-5.txt +143 -143
- package/src/engine/session/prompt/default.txt +105 -105
- package/src/engine/session/prompt/gemini.txt +155 -155
- package/src/engine/session/prompt/gpt.txt +107 -107
- package/src/engine/session/prompt/kimi.txt +95 -95
- package/src/engine/session/prompt/max-steps.txt +15 -15
- package/src/engine/session/prompt/plan-reminder-anthropic.txt +67 -67
- package/src/engine/session/prompt/plan.txt +26 -26
- package/src/engine/session/prompt/trinity.txt +97 -97
- package/src/engine/session/prompt.ts +66 -9
- package/src/engine/session/retry.ts +200 -200
- package/src/engine/session/revert.ts +162 -162
- package/src/engine/session/run-state.ts +153 -153
- package/src/engine/session/schema.ts +26 -26
- package/src/engine/session/session.sql.ts +137 -137
- package/src/engine/session/session.ts +1011 -1011
- package/src/engine/session/status.ts +94 -94
- package/src/engine/session/summary.ts +164 -164
- package/src/engine/session/system.ts +84 -84
- package/src/engine/session/todo.ts +81 -81
- package/src/engine/share/session.ts +61 -61
- package/src/engine/share/share-next.ts +376 -376
- package/src/engine/share/share.sql.ts +13 -13
- package/src/engine/shell/shell/shell.ts +215 -215
- package/src/engine/shell/shell.ts +215 -215
- package/src/engine/skill/discovery.ts +116 -116
- package/src/engine/skill/index.ts +336 -336
- package/src/engine/skill/prompt/customize-opencode.md +377 -377
- package/src/engine/skill/skill/discovery.ts +116 -116
- package/src/engine/skill/skill/index.ts +336 -336
- package/src/engine/skill/skill/prompt/customize-opencode.md +377 -377
- package/src/engine/snapshot/index.ts +762 -762
- package/src/engine/snapshot/snapshot/index.ts +762 -762
- package/src/engine/sync/README.md +179 -179
- package/src/engine/sync/event.sql.ts +17 -17
- package/src/engine/sync/index.ts +410 -410
- package/src/engine/sync/schema.ts +11 -11
- package/src/engine/temporary.ts +33 -33
- package/src/engine/tool/apply_patch.ts +313 -313
- package/src/engine/tool/apply_patch.txt +33 -33
- package/src/engine/tool/edit.ts +711 -711
- package/src/engine/tool/edit.txt +10 -10
- package/src/engine/tool/external-directory.ts +49 -49
- package/src/engine/tool/glob.ts +103 -103
- package/src/engine/tool/glob.txt +6 -6
- package/src/engine/tool/grep.ts +156 -156
- package/src/engine/tool/grep.txt +8 -8
- package/src/engine/tool/invalid.ts +21 -21
- package/src/engine/tool/json-schema.ts +164 -164
- package/src/engine/tool/lsp.ts +113 -113
- package/src/engine/tool/lsp.txt +24 -24
- package/src/engine/tool/mcp-websearch.ts +96 -96
- package/src/engine/tool/plan-enter.txt +14 -14
- package/src/engine/tool/plan-exit.txt +13 -13
- package/src/engine/tool/plan.ts +78 -78
- package/src/engine/tool/question.ts +44 -44
- package/src/engine/tool/question.txt +10 -10
- package/src/engine/tool/read.ts +337 -337
- package/src/engine/tool/read.txt +14 -14
- package/src/engine/tool/registry.ts +472 -472
- package/src/engine/tool/repo_clone.ts +80 -80
- package/src/engine/tool/repo_clone.txt +5 -5
- package/src/engine/tool/repo_overview.ts +279 -279
- package/src/engine/tool/repo_overview.txt +4 -4
- package/src/engine/tool/schema.ts +14 -14
- package/src/engine/tool/shell/id.ts +19 -19
- package/src/engine/tool/shell/prompt.ts +295 -295
- package/src/engine/tool/shell/shell.txt +77 -77
- package/src/engine/tool/shell.ts +647 -647
- package/src/engine/tool/skill.ts +75 -75
- package/src/engine/tool/skill.txt +5 -5
- package/src/engine/tool/task.ts +337 -337
- package/src/engine/tool/task.txt +58 -58
- package/src/engine/tool/task_status.ts +179 -179
- package/src/engine/tool/task_status.txt +13 -13
- package/src/engine/tool/todo.ts +57 -57
- package/src/engine/tool/todowrite.txt +167 -167
- package/src/engine/tool/tool/apply_patch.ts +313 -313
- package/src/engine/tool/tool/apply_patch.txt +33 -33
- package/src/engine/tool/tool/edit.ts +711 -711
- package/src/engine/tool/tool/edit.txt +10 -10
- package/src/engine/tool/tool/external-directory.ts +49 -49
- package/src/engine/tool/tool/glob.ts +103 -103
- package/src/engine/tool/tool/glob.txt +6 -6
- package/src/engine/tool/tool/grep.ts +156 -156
- package/src/engine/tool/tool/grep.txt +8 -8
- package/src/engine/tool/tool/invalid.ts +21 -21
- package/src/engine/tool/tool/json-schema.ts +164 -164
- package/src/engine/tool/tool/lsp.ts +113 -113
- package/src/engine/tool/tool/lsp.txt +24 -24
- package/src/engine/tool/tool/mcp-websearch.ts +96 -96
- package/src/engine/tool/tool/plan-enter.txt +14 -14
- package/src/engine/tool/tool/plan-exit.txt +13 -13
- package/src/engine/tool/tool/plan.ts +78 -78
- package/src/engine/tool/tool/question.ts +44 -44
- package/src/engine/tool/tool/question.txt +10 -10
- package/src/engine/tool/tool/read.ts +337 -337
- package/src/engine/tool/tool/read.txt +14 -14
- package/src/engine/tool/tool/registry.ts +472 -472
- package/src/engine/tool/tool/repo_clone.ts +80 -80
- package/src/engine/tool/tool/repo_clone.txt +5 -5
- package/src/engine/tool/tool/repo_overview.ts +279 -279
- package/src/engine/tool/tool/repo_overview.txt +4 -4
- package/src/engine/tool/tool/schema.ts +14 -14
- package/src/engine/tool/tool/shell/id.ts +19 -19
- package/src/engine/tool/tool/shell/prompt.ts +295 -295
- package/src/engine/tool/tool/shell/shell.txt +77 -77
- package/src/engine/tool/tool/shell.ts +647 -647
- package/src/engine/tool/tool/skill.ts +75 -75
- package/src/engine/tool/tool/skill.txt +5 -5
- package/src/engine/tool/tool/task.ts +337 -337
- package/src/engine/tool/tool/task.txt +58 -58
- package/src/engine/tool/tool/task_status.ts +179 -179
- package/src/engine/tool/tool/task_status.txt +13 -13
- package/src/engine/tool/tool/todo.ts +57 -57
- package/src/engine/tool/tool/todowrite.txt +167 -167
- package/src/engine/tool/tool/tool.ts +164 -164
- package/src/engine/tool/tool/truncate.ts +160 -160
- package/src/engine/tool/tool/truncation-dir.ts +4 -4
- package/src/engine/tool/tool/webfetch.ts +192 -192
- package/src/engine/tool/tool/webfetch.txt +13 -13
- package/src/engine/tool/tool/websearch.ts +143 -143
- package/src/engine/tool/tool/websearch.txt +14 -14
- package/src/engine/tool/tool/write.ts +104 -104
- package/src/engine/tool/tool/write.txt +8 -8
- package/src/engine/tool/tool.ts +164 -164
- package/src/engine/tool/truncate.ts +160 -160
- package/src/engine/tool/truncation-dir.ts +4 -4
- package/src/engine/tool/webfetch.ts +192 -192
- package/src/engine/tool/webfetch.txt +13 -13
- package/src/engine/tool/websearch.ts +143 -143
- package/src/engine/tool/websearch.txt +14 -14
- package/src/engine/tool/write.ts +104 -104
- package/src/engine/tool/write.txt +8 -8
- package/src/engine/util/archive.ts +17 -17
- package/src/engine/util/bom.ts +31 -31
- package/src/engine/util/data-url.ts +9 -9
- package/src/engine/util/defer.ts +10 -10
- package/src/engine/util/effect-http-client.ts +11 -11
- package/src/engine/util/error.ts +88 -88
- package/src/engine/util/filesystem.ts +252 -252
- package/src/engine/util/format.ts +20 -20
- package/src/engine/util/iife.ts +3 -3
- package/src/engine/util/lazy.ts +20 -20
- package/src/engine/util/local-context.ts +25 -25
- package/src/engine/util/locale.ts +86 -86
- package/src/engine/util/media.ts +26 -26
- package/src/engine/util/process.ts +176 -176
- package/src/engine/util/queue.ts +32 -32
- package/src/engine/util/record.ts +3 -3
- package/src/engine/util/repository.ts +158 -158
- package/src/engine/util/rpc.ts +66 -66
- package/src/engine/util/signal.ts +12 -12
- package/src/engine/util/timeout.ts +13 -13
- package/src/engine/util/token.ts +7 -7
- package/src/engine/util/util/archive.ts +17 -17
- package/src/engine/util/util/bom.ts +31 -31
- package/src/engine/util/util/data-url.ts +9 -9
- package/src/engine/util/util/defer.ts +10 -10
- package/src/engine/util/util/effect-http-client.ts +11 -11
- package/src/engine/util/util/error.ts +88 -88
- package/src/engine/util/util/filesystem.ts +252 -252
- package/src/engine/util/util/format.ts +20 -20
- package/src/engine/util/util/iife.ts +3 -3
- package/src/engine/util/util/lazy.ts +20 -20
- package/src/engine/util/util/local-context.ts +25 -25
- package/src/engine/util/util/locale.ts +86 -86
- package/src/engine/util/util/media.ts +26 -26
- package/src/engine/util/util/process.ts +176 -176
- package/src/engine/util/util/queue.ts +32 -32
- package/src/engine/util/util/record.ts +3 -3
- package/src/engine/util/util/repository.ts +158 -158
- package/src/engine/util/util/rpc.ts +66 -66
- package/src/engine/util/util/signal.ts +12 -12
- package/src/engine/util/util/timeout.ts +13 -13
- package/src/engine/util/util/token.ts +7 -7
- package/src/engine/util/util/which.ts +14 -14
- package/src/engine/util/util/wildcard.ts +59 -59
- package/src/engine/util/which.ts +14 -14
- package/src/engine/util/wildcard.ts +59 -59
- package/src/engine/worktree/index.ts +621 -621
- package/src/server.ts +121 -158
- package/src/tui.ts +485 -502
|
@@ -1,294 +1,294 @@
|
|
|
1
|
-
// Generated by BoneScript compiler. DO NOT EDIT.
|
|
2
|
-
// Service: SessionService
|
|
3
|
-
import { Router, Request, Response } from "express";
|
|
4
|
-
import { v4 as uuid } from "uuid";
|
|
5
|
-
import { query, queryOne, execute, pool } from "../db";
|
|
6
|
-
import { eventBus } from "../events";
|
|
7
|
-
import { requireAuth, AuthContext } from "../auth";
|
|
8
|
-
import rateLimit from "express-rate-limit";
|
|
9
|
-
import { auditLog } from "../audit";
|
|
10
|
-
import { logger } from "../logger";
|
|
11
|
-
import { counter } from "../metrics";
|
|
12
|
-
import * as __algorithms from "../algorithms";
|
|
13
|
-
const { shortestPath, topologicalSort, binarySearch, bipartiteMatching, roundRobin, weightedAverage, percentile, rankBy, consistentHash } = __algorithms as any;
|
|
14
|
-
|
|
15
|
-
import { transitionSession, SESSION_INITIAL } from "../state_machines/session";
|
|
16
|
-
|
|
17
|
-
export const sessionsRouter = Router();
|
|
18
|
-
|
|
19
|
-
// Rate limiter from policy declaration
|
|
20
|
-
const __routeRateLimit = rateLimit({ windowMs: 60000, max: 500, standardHeaders: true, legacyHeaders: false });
|
|
21
|
-
|
|
22
|
-
// CREATE
|
|
23
|
-
sessionsRouter.post("/", __routeRateLimit, requireAuth, async (req: Request, res: Response) => {
|
|
24
|
-
try {
|
|
25
|
-
const id = uuid();
|
|
26
|
-
const { slug, project_id, workspace_id, parent_id, directory, title, version, share_url, summary_additions, summary_deletions, summary_files, summary_diffs, revert_data, permission_ruleset } = req.body;
|
|
27
|
-
const state = SESSION_INITIAL;
|
|
28
|
-
const sql = `INSERT INTO sessions (id, slug, project_id, workspace_id, parent_id, directory, title, version, share_url, summary_additions, summary_deletions, summary_files, summary_diffs, revert_data, permission_ruleset, state) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16) RETURNING *`;
|
|
29
|
-
const rows = await query(sql, [id, slug, project_id, workspace_id, parent_id, directory, title, version, share_url, summary_additions, summary_deletions, summary_files, summary_diffs, revert_data, permission_ruleset, state]);
|
|
30
|
-
counter("entity.created", { entity: "Session" });
|
|
31
|
-
res.status(201).json(rows[0]);
|
|
32
|
-
} catch (e: any) {
|
|
33
|
-
res.status(400).json({ error: { code: "CREATE_FAILED", message: e.message } });
|
|
34
|
-
}
|
|
35
|
-
});
|
|
36
|
-
|
|
37
|
-
// READ
|
|
38
|
-
sessionsRouter.get("/:id", __routeRateLimit, requireAuth, async (req: Request, res: Response) => {
|
|
39
|
-
try {
|
|
40
|
-
const row = await queryOne(`SELECT * FROM sessions WHERE id = $1`, [req.params.id]);
|
|
41
|
-
if (!row) return res.status(404).json({ error: { code: "NOT_FOUND", message: "Not found" } });
|
|
42
|
-
res.json(row);
|
|
43
|
-
} catch (e: any) {
|
|
44
|
-
res.status(500).json({ error: { code: "DB_ERROR", message: e.message } });
|
|
45
|
-
}
|
|
46
|
-
});
|
|
47
|
-
|
|
48
|
-
// LIST
|
|
49
|
-
sessionsRouter.get("/", __routeRateLimit, requireAuth, async (req: Request, res: Response) => {
|
|
50
|
-
try {
|
|
51
|
-
const page = parseInt(req.query.page as string) || 1;
|
|
52
|
-
const pageSize = Math.min(parseInt(req.query.page_size as string) || 50, 100);
|
|
53
|
-
const offset = (page - 1) * pageSize;
|
|
54
|
-
const rows = await query(`SELECT * FROM sessions ORDER BY created_at DESC LIMIT $1 OFFSET $2`, [pageSize, offset]);
|
|
55
|
-
const [{ count }] = await query(`SELECT COUNT(*) as count FROM sessions`);
|
|
56
|
-
res.json({ items: rows, total: parseInt(count), page, page_size: pageSize });
|
|
57
|
-
} catch (e: any) {
|
|
58
|
-
res.status(500).json({ error: { code: "DB_ERROR", message: e.message } });
|
|
59
|
-
}
|
|
60
|
-
});
|
|
61
|
-
|
|
62
|
-
// UPDATE
|
|
63
|
-
sessionsRouter.put("/:id", __routeRateLimit, requireAuth, async (req: Request, res: Response) => {
|
|
64
|
-
const fields = { ...req.body };
|
|
65
|
-
// State machine enforcement
|
|
66
|
-
if (fields.state !== undefined) {
|
|
67
|
-
const current = await queryOne<{ state: string }>(`SELECT state FROM sessions WHERE id = $1`, [req.params.id]);
|
|
68
|
-
if (!current) return res.status(404).json({ error: { code: "NOT_FOUND", message: "Not found" } });
|
|
69
|
-
// Find the trigger for this state transition
|
|
70
|
-
const trigger = `${current.state}_to_${fields.state}`;
|
|
71
|
-
const tr = transitionSession(current.state as any, trigger);
|
|
72
|
-
if (!tr.ok) return res.status(422).json({ error: { code: "INVALID_TRANSITION", message: `Cannot transition from ${current.state} to ${fields.state}` } });
|
|
73
|
-
}
|
|
74
|
-
const sets = Object.keys(fields).map((k, i) => `${k} = $${i + 2}`).join(", ");
|
|
75
|
-
const values = Object.values(fields);
|
|
76
|
-
const sql = `UPDATE sessions SET ${sets}, updated_at = NOW() WHERE id = $1 RETURNING *`;
|
|
77
|
-
const rows = await query(sql, [req.params.id, ...values]);
|
|
78
|
-
if (rows.length === 0) return res.status(404).json({ error: { code: "NOT_FOUND", message: "Not found" } });
|
|
79
|
-
res.json(rows[0]);
|
|
80
|
-
});
|
|
81
|
-
|
|
82
|
-
// DELETE
|
|
83
|
-
sessionsRouter.delete("/:id", __routeRateLimit, requireAuth, async (req: Request, res: Response) => {
|
|
84
|
-
try {
|
|
85
|
-
const count = await execute(`DELETE FROM sessions WHERE id = $1`, [req.params.id]);
|
|
86
|
-
if (count === 0) return res.status(404).json({ error: { code: "NOT_FOUND", message: "Not found" } });
|
|
87
|
-
res.status(204).send();
|
|
88
|
-
} catch (e: any) {
|
|
89
|
-
res.status(500).json({ error: { code: "DB_ERROR", message: e.message } });
|
|
90
|
-
}
|
|
91
|
-
});
|
|
92
|
-
|
|
93
|
-
// CAPABILITY: archive_session [transactional]
|
|
94
|
-
sessionsRouter.post("/archive-session", __routeRateLimit, requireAuth, auditLog("archive_session", "Session"), async (req: Request, res: Response) => {
|
|
95
|
-
const auth: AuthContext = (req as any).auth;
|
|
96
|
-
const __client = await pool.connect();
|
|
97
|
-
try {
|
|
98
|
-
await __client.query("BEGIN");
|
|
99
|
-
// Fetch entities
|
|
100
|
-
const session = await queryOne(`SELECT * FROM sessions WHERE id = $1`, [req.body.session_id || req.params.id]);
|
|
101
|
-
if (!session) {
|
|
102
|
-
return res.status(404).json({ error: { code: "NOT_FOUND", message: "session not found" } });
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
// Preconditions
|
|
106
|
-
if (!([["active", "busy", "compacting"]].flat().includes(session?.state))) {
|
|
107
|
-
return res.status(422).json({ error: { code: "PRECONDITION_FAILED", message: "session.state in [\\\"active\\\", \\\"busy\\\", \\\"compacting\\\"]" } });
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
// Effects (applied in declaration order)
|
|
111
|
-
const __effect_0 = await query(`UPDATE sessions SET state = $1, updated_at = NOW() WHERE id = $2 RETURNING *`, ["archived", req.body.session_id || req.params.id]);
|
|
112
|
-
if (!__effect_0 || __effect_0.length === 0) {
|
|
113
|
-
throw new Error("Effect failed: session.state = \"archived\"");
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
// Emit events
|
|
117
|
-
await eventBus.publish("SessionStateChanged", { session_id: session?.id, timestamp: new Date().toISOString(), actor_id: auth.actor_id }, "SessionService", auth.trace_id, __client);
|
|
118
|
-
|
|
119
|
-
res.json({ ok: true, action: "archive_session", entity: session });
|
|
120
|
-
await __client.query("COMMIT");
|
|
121
|
-
} catch (e: any) {
|
|
122
|
-
await __client.query("ROLLBACK");
|
|
123
|
-
res.status(400).json({ error: { code: "CAPABILITY_FAILED", message: e.message } });
|
|
124
|
-
} finally {
|
|
125
|
-
__client.release();
|
|
126
|
-
}
|
|
127
|
-
});
|
|
128
|
-
|
|
129
|
-
// CAPABILITY: delete_session [transactional]
|
|
130
|
-
sessionsRouter.post("/delete-session", __routeRateLimit, requireAuth, auditLog("delete_session", "Session"), async (req: Request, res: Response) => {
|
|
131
|
-
const auth: AuthContext = (req as any).auth;
|
|
132
|
-
const __client = await pool.connect();
|
|
133
|
-
try {
|
|
134
|
-
await __client.query("BEGIN");
|
|
135
|
-
// Fetch entities
|
|
136
|
-
const session = await queryOne(`SELECT * FROM sessions WHERE id = $1`, [req.body.session_id || req.params.id]);
|
|
137
|
-
if (!session) {
|
|
138
|
-
return res.status(404).json({ error: { code: "NOT_FOUND", message: "session not found" } });
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
// Preconditions
|
|
142
|
-
if (!(session?.state !== "deleted")) {
|
|
143
|
-
return res.status(422).json({ error: { code: "PRECONDITION_FAILED", message: "session.state != \\\"deleted\\\"" } });
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
// Effects (applied in declaration order)
|
|
147
|
-
const __effect_0 = await query(`UPDATE sessions SET state = $1, updated_at = NOW() WHERE id = $2 RETURNING *`, ["deleted", req.body.session_id || req.params.id]);
|
|
148
|
-
if (!__effect_0 || __effect_0.length === 0) {
|
|
149
|
-
throw new Error("Effect failed: session.state = \"deleted\"");
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
// Emit events
|
|
153
|
-
await eventBus.publish("SessionStateChanged", { session_id: session?.id, timestamp: new Date().toISOString(), actor_id: auth.actor_id }, "SessionService", auth.trace_id, __client);
|
|
154
|
-
|
|
155
|
-
res.json({ ok: true, action: "delete_session", entity: session });
|
|
156
|
-
await __client.query("COMMIT");
|
|
157
|
-
} catch (e: any) {
|
|
158
|
-
await __client.query("ROLLBACK");
|
|
159
|
-
res.status(400).json({ error: { code: "CAPABILITY_FAILED", message: e.message } });
|
|
160
|
-
} finally {
|
|
161
|
-
__client.release();
|
|
162
|
-
}
|
|
163
|
-
});
|
|
164
|
-
|
|
165
|
-
// CAPABILITY: add_message [transactional]
|
|
166
|
-
sessionsRouter.post("/add-message", __routeRateLimit, requireAuth, auditLog("add_message", "Session"), async (req: Request, res: Response) => {
|
|
167
|
-
const auth: AuthContext = (req as any).auth;
|
|
168
|
-
const __client = await pool.connect();
|
|
169
|
-
try {
|
|
170
|
-
await __client.query("BEGIN");
|
|
171
|
-
const { role, data } = req.body;
|
|
172
|
-
|
|
173
|
-
// Fetch entities
|
|
174
|
-
const session = await queryOne(`SELECT * FROM sessions WHERE id = $1`, [req.body.session_id || req.params.id]);
|
|
175
|
-
if (!session) {
|
|
176
|
-
return res.status(404).json({ error: { code: "NOT_FOUND", message: "session not found" } });
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
// Preconditions
|
|
180
|
-
if (!([["active", "busy"]].flat().includes(session?.state))) {
|
|
181
|
-
return res.status(422).json({ error: { code: "PRECONDITION_FAILED", message: "session.state in [\\\"active\\\", \\\"busy\\\"]" } });
|
|
182
|
-
}
|
|
183
|
-
if (!([["user", "assistant", "system", "tool"]].flat().includes(role))) {
|
|
184
|
-
return res.status(422).json({ error: { code: "PRECONDITION_FAILED", message: "role in [\\\"user\\\", \\\"assistant\\\", \\\"system\\\", \\\"tool\\\"]" } });
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
// Emit events
|
|
188
|
-
await eventBus.publish("MessageAdded", { session_id: session?.id, timestamp: new Date().toISOString(), actor_id: auth.actor_id }, "SessionService", auth.trace_id, __client);
|
|
189
|
-
|
|
190
|
-
res.json({ ok: true, action: "add_message", entity: session });
|
|
191
|
-
await __client.query("COMMIT");
|
|
192
|
-
} catch (e: any) {
|
|
193
|
-
await __client.query("ROLLBACK");
|
|
194
|
-
res.status(400).json({ error: { code: "CAPABILITY_FAILED", message: e.message } });
|
|
195
|
-
} finally {
|
|
196
|
-
__client.release();
|
|
197
|
-
}
|
|
198
|
-
});
|
|
199
|
-
|
|
200
|
-
// CAPABILITY: update_part
|
|
201
|
-
sessionsRouter.post("/update-part", __routeRateLimit, requireAuth, auditLog("update_part", "Session"), async (req: Request, res: Response) => {
|
|
202
|
-
const auth: AuthContext = (req as any).auth;
|
|
203
|
-
try {
|
|
204
|
-
// sync: realtime — execute then broadcast to WebSocket channel
|
|
205
|
-
const { message_id, part_id, data } = req.body;
|
|
206
|
-
|
|
207
|
-
// Fetch entities
|
|
208
|
-
const session = await queryOne(`SELECT * FROM sessions WHERE id = $1`, [req.body.session_id || req.params.id]);
|
|
209
|
-
if (!session) {
|
|
210
|
-
return res.status(404).json({ error: { code: "NOT_FOUND", message: "session not found" } });
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
// Preconditions
|
|
214
|
-
if (!([["active", "busy"]].flat().includes(session?.state))) {
|
|
215
|
-
return res.status(422).json({ error: { code: "PRECONDITION_FAILED", message: "session.state in [\\\"active\\\", \\\"busy\\\"]" } });
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
// Emit events
|
|
219
|
-
await eventBus.publish("PartUpdated", { session_id: session?.id, timestamp: new Date().toISOString(), actor_id: auth.actor_id }, "SessionService", auth.trace_id);
|
|
220
|
-
|
|
221
|
-
res.json({ ok: true, action: "update_part", entity: session });
|
|
222
|
-
// Broadcast to WebSocket subscribers after successful execution
|
|
223
|
-
const { broadcastToChannel: _broadcast } = require("../websocket") as any;
|
|
224
|
-
if (typeof _broadcast === "function") {
|
|
225
|
-
_broadcast("SessionService", { type: "update_part", payload: req.body, actor: auth.actor_id });
|
|
226
|
-
}
|
|
227
|
-
} catch (e: any) {
|
|
228
|
-
res.status(400).json({ error: { code: "CAPABILITY_FAILED", message: e.message } });
|
|
229
|
-
}
|
|
230
|
-
});
|
|
231
|
-
|
|
232
|
-
// CAPABILITY: compact_session [transactional]
|
|
233
|
-
sessionsRouter.post("/compact-session", __routeRateLimit, requireAuth, auditLog("compact_session", "Session"), async (req: Request, res: Response) => {
|
|
234
|
-
const auth: AuthContext = (req as any).auth;
|
|
235
|
-
const __client = await pool.connect();
|
|
236
|
-
try {
|
|
237
|
-
await __client.query("BEGIN");
|
|
238
|
-
// Fetch entities
|
|
239
|
-
const session = await queryOne(`SELECT * FROM sessions WHERE id = $1`, [req.body.session_id || req.params.id]);
|
|
240
|
-
if (!session) {
|
|
241
|
-
return res.status(404).json({ error: { code: "NOT_FOUND", message: "session not found" } });
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
// Preconditions
|
|
245
|
-
if (!(session?.state === "active")) {
|
|
246
|
-
return res.status(422).json({ error: { code: "PRECONDITION_FAILED", message: "session.state == \\\"active\\\"" } });
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
// Effects (applied in declaration order)
|
|
250
|
-
const __effect_0 = await query(`UPDATE sessions SET state = $1, updated_at = NOW() WHERE id = $2 RETURNING *`, ["compacting", req.body.session_id || req.params.id]);
|
|
251
|
-
if (!__effect_0 || __effect_0.length === 0) {
|
|
252
|
-
throw new Error("Effect failed: session.state = \"compacting\"");
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
// Emit events
|
|
256
|
-
await eventBus.publish("SessionStateChanged", { session_id: session?.id, timestamp: new Date().toISOString(), actor_id: auth.actor_id }, "SessionService", auth.trace_id, __client);
|
|
257
|
-
|
|
258
|
-
res.json({ ok: true, action: "compact_session", entity: session });
|
|
259
|
-
await __client.query("COMMIT");
|
|
260
|
-
} catch (e: any) {
|
|
261
|
-
await __client.query("ROLLBACK");
|
|
262
|
-
res.status(400).json({ error: { code: "CAPABILITY_FAILED", message: e.message } });
|
|
263
|
-
} finally {
|
|
264
|
-
__client.release();
|
|
265
|
-
}
|
|
266
|
-
});
|
|
267
|
-
|
|
268
|
-
// RELATION: messages (has_many Message)
|
|
269
|
-
sessionsRouter.get("/:id/messages", requireAuth, async (req: Request, res: Response) => {
|
|
270
|
-
try {
|
|
271
|
-
const page = parseInt(req.query.page as string) || 1;
|
|
272
|
-
const pageSize = Math.min(parseInt(req.query.page_size as string) || 50, 100);
|
|
273
|
-
const offset = (page - 1) * pageSize;
|
|
274
|
-
const rows = await query(`SELECT * FROM messages WHERE session_id = $1 ORDER BY created_at DESC LIMIT $2 OFFSET $3`, [req.params.id, pageSize, offset]);
|
|
275
|
-
const [{ count }] = await query(`SELECT COUNT(*) as count FROM messages WHERE session_id = $1`, [req.params.id]);
|
|
276
|
-
res.json({ items: rows, total: parseInt(count), page, page_size: pageSize });
|
|
277
|
-
} catch (e: any) {
|
|
278
|
-
res.status(500).json({ error: { code: "DB_ERROR", message: e.message } });
|
|
279
|
-
}
|
|
280
|
-
});
|
|
281
|
-
|
|
282
|
-
// RELATION: tool_calls (has_many ToolCall)
|
|
283
|
-
sessionsRouter.get("/:id/tool_calls", requireAuth, async (req: Request, res: Response) => {
|
|
284
|
-
try {
|
|
285
|
-
const page = parseInt(req.query.page as string) || 1;
|
|
286
|
-
const pageSize = Math.min(parseInt(req.query.page_size as string) || 50, 100);
|
|
287
|
-
const offset = (page - 1) * pageSize;
|
|
288
|
-
const rows = await query(`SELECT * FROM tool_calls WHERE session_id = $1 ORDER BY created_at DESC LIMIT $2 OFFSET $3`, [req.params.id, pageSize, offset]);
|
|
289
|
-
const [{ count }] = await query(`SELECT COUNT(*) as count FROM tool_calls WHERE session_id = $1`, [req.params.id]);
|
|
290
|
-
res.json({ items: rows, total: parseInt(count), page, page_size: pageSize });
|
|
291
|
-
} catch (e: any) {
|
|
292
|
-
res.status(500).json({ error: { code: "DB_ERROR", message: e.message } });
|
|
293
|
-
}
|
|
294
|
-
});
|
|
1
|
+
// Generated by BoneScript compiler. DO NOT EDIT.
|
|
2
|
+
// Service: SessionService
|
|
3
|
+
import { Router, Request, Response } from "express";
|
|
4
|
+
import { v4 as uuid } from "uuid";
|
|
5
|
+
import { query, queryOne, execute, pool } from "../db";
|
|
6
|
+
import { eventBus } from "../events";
|
|
7
|
+
import { requireAuth, AuthContext } from "../auth";
|
|
8
|
+
import rateLimit from "express-rate-limit";
|
|
9
|
+
import { auditLog } from "../audit";
|
|
10
|
+
import { logger } from "../logger";
|
|
11
|
+
import { counter } from "../metrics";
|
|
12
|
+
import * as __algorithms from "../algorithms";
|
|
13
|
+
const { shortestPath, topologicalSort, binarySearch, bipartiteMatching, roundRobin, weightedAverage, percentile, rankBy, consistentHash } = __algorithms as any;
|
|
14
|
+
|
|
15
|
+
import { transitionSession, SESSION_INITIAL } from "../state_machines/session";
|
|
16
|
+
|
|
17
|
+
export const sessionsRouter = Router();
|
|
18
|
+
|
|
19
|
+
// Rate limiter from policy declaration
|
|
20
|
+
const __routeRateLimit = rateLimit({ windowMs: 60000, max: 500, standardHeaders: true, legacyHeaders: false });
|
|
21
|
+
|
|
22
|
+
// CREATE
|
|
23
|
+
sessionsRouter.post("/", __routeRateLimit, requireAuth, async (req: Request, res: Response) => {
|
|
24
|
+
try {
|
|
25
|
+
const id = uuid();
|
|
26
|
+
const { slug, project_id, workspace_id, parent_id, directory, title, version, share_url, summary_additions, summary_deletions, summary_files, summary_diffs, revert_data, permission_ruleset } = req.body;
|
|
27
|
+
const state = SESSION_INITIAL;
|
|
28
|
+
const sql = `INSERT INTO sessions (id, slug, project_id, workspace_id, parent_id, directory, title, version, share_url, summary_additions, summary_deletions, summary_files, summary_diffs, revert_data, permission_ruleset, state) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16) RETURNING *`;
|
|
29
|
+
const rows = await query(sql, [id, slug, project_id, workspace_id, parent_id, directory, title, version, share_url, summary_additions, summary_deletions, summary_files, summary_diffs, revert_data, permission_ruleset, state]);
|
|
30
|
+
counter("entity.created", { entity: "Session" });
|
|
31
|
+
res.status(201).json(rows[0]);
|
|
32
|
+
} catch (e: any) {
|
|
33
|
+
res.status(400).json({ error: { code: "CREATE_FAILED", message: e.message } });
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
// READ
|
|
38
|
+
sessionsRouter.get("/:id", __routeRateLimit, requireAuth, async (req: Request, res: Response) => {
|
|
39
|
+
try {
|
|
40
|
+
const row = await queryOne(`SELECT * FROM sessions WHERE id = $1`, [req.params.id]);
|
|
41
|
+
if (!row) return res.status(404).json({ error: { code: "NOT_FOUND", message: "Not found" } });
|
|
42
|
+
res.json(row);
|
|
43
|
+
} catch (e: any) {
|
|
44
|
+
res.status(500).json({ error: { code: "DB_ERROR", message: e.message } });
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
// LIST
|
|
49
|
+
sessionsRouter.get("/", __routeRateLimit, requireAuth, async (req: Request, res: Response) => {
|
|
50
|
+
try {
|
|
51
|
+
const page = parseInt(req.query.page as string) || 1;
|
|
52
|
+
const pageSize = Math.min(parseInt(req.query.page_size as string) || 50, 100);
|
|
53
|
+
const offset = (page - 1) * pageSize;
|
|
54
|
+
const rows = await query(`SELECT * FROM sessions ORDER BY created_at DESC LIMIT $1 OFFSET $2`, [pageSize, offset]);
|
|
55
|
+
const [{ count }] = await query(`SELECT COUNT(*) as count FROM sessions`);
|
|
56
|
+
res.json({ items: rows, total: parseInt(count), page, page_size: pageSize });
|
|
57
|
+
} catch (e: any) {
|
|
58
|
+
res.status(500).json({ error: { code: "DB_ERROR", message: e.message } });
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
// UPDATE
|
|
63
|
+
sessionsRouter.put("/:id", __routeRateLimit, requireAuth, async (req: Request, res: Response) => {
|
|
64
|
+
const fields = { ...req.body };
|
|
65
|
+
// State machine enforcement
|
|
66
|
+
if (fields.state !== undefined) {
|
|
67
|
+
const current = await queryOne<{ state: string }>(`SELECT state FROM sessions WHERE id = $1`, [req.params.id]);
|
|
68
|
+
if (!current) return res.status(404).json({ error: { code: "NOT_FOUND", message: "Not found" } });
|
|
69
|
+
// Find the trigger for this state transition
|
|
70
|
+
const trigger = `${current.state}_to_${fields.state}`;
|
|
71
|
+
const tr = transitionSession(current.state as any, trigger);
|
|
72
|
+
if (!tr.ok) return res.status(422).json({ error: { code: "INVALID_TRANSITION", message: `Cannot transition from ${current.state} to ${fields.state}` } });
|
|
73
|
+
}
|
|
74
|
+
const sets = Object.keys(fields).map((k, i) => `${k} = $${i + 2}`).join(", ");
|
|
75
|
+
const values = Object.values(fields);
|
|
76
|
+
const sql = `UPDATE sessions SET ${sets}, updated_at = NOW() WHERE id = $1 RETURNING *`;
|
|
77
|
+
const rows = await query(sql, [req.params.id, ...values]);
|
|
78
|
+
if (rows.length === 0) return res.status(404).json({ error: { code: "NOT_FOUND", message: "Not found" } });
|
|
79
|
+
res.json(rows[0]);
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
// DELETE
|
|
83
|
+
sessionsRouter.delete("/:id", __routeRateLimit, requireAuth, async (req: Request, res: Response) => {
|
|
84
|
+
try {
|
|
85
|
+
const count = await execute(`DELETE FROM sessions WHERE id = $1`, [req.params.id]);
|
|
86
|
+
if (count === 0) return res.status(404).json({ error: { code: "NOT_FOUND", message: "Not found" } });
|
|
87
|
+
res.status(204).send();
|
|
88
|
+
} catch (e: any) {
|
|
89
|
+
res.status(500).json({ error: { code: "DB_ERROR", message: e.message } });
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
// CAPABILITY: archive_session [transactional]
|
|
94
|
+
sessionsRouter.post("/archive-session", __routeRateLimit, requireAuth, auditLog("archive_session", "Session"), async (req: Request, res: Response) => {
|
|
95
|
+
const auth: AuthContext = (req as any).auth;
|
|
96
|
+
const __client = await pool.connect();
|
|
97
|
+
try {
|
|
98
|
+
await __client.query("BEGIN");
|
|
99
|
+
// Fetch entities
|
|
100
|
+
const session = await queryOne(`SELECT * FROM sessions WHERE id = $1`, [req.body.session_id || req.params.id]);
|
|
101
|
+
if (!session) {
|
|
102
|
+
return res.status(404).json({ error: { code: "NOT_FOUND", message: "session not found" } });
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// Preconditions
|
|
106
|
+
if (!([["active", "busy", "compacting"]].flat().includes(session?.state))) {
|
|
107
|
+
return res.status(422).json({ error: { code: "PRECONDITION_FAILED", message: "session.state in [\\\"active\\\", \\\"busy\\\", \\\"compacting\\\"]" } });
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// Effects (applied in declaration order)
|
|
111
|
+
const __effect_0 = await query(`UPDATE sessions SET state = $1, updated_at = NOW() WHERE id = $2 RETURNING *`, ["archived", req.body.session_id || req.params.id]);
|
|
112
|
+
if (!__effect_0 || __effect_0.length === 0) {
|
|
113
|
+
throw new Error("Effect failed: session.state = \"archived\"");
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// Emit events
|
|
117
|
+
await eventBus.publish("SessionStateChanged", { session_id: session?.id, timestamp: new Date().toISOString(), actor_id: auth.actor_id }, "SessionService", auth.trace_id, __client);
|
|
118
|
+
|
|
119
|
+
res.json({ ok: true, action: "archive_session", entity: session });
|
|
120
|
+
await __client.query("COMMIT");
|
|
121
|
+
} catch (e: any) {
|
|
122
|
+
await __client.query("ROLLBACK");
|
|
123
|
+
res.status(400).json({ error: { code: "CAPABILITY_FAILED", message: e.message } });
|
|
124
|
+
} finally {
|
|
125
|
+
__client.release();
|
|
126
|
+
}
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
// CAPABILITY: delete_session [transactional]
|
|
130
|
+
sessionsRouter.post("/delete-session", __routeRateLimit, requireAuth, auditLog("delete_session", "Session"), async (req: Request, res: Response) => {
|
|
131
|
+
const auth: AuthContext = (req as any).auth;
|
|
132
|
+
const __client = await pool.connect();
|
|
133
|
+
try {
|
|
134
|
+
await __client.query("BEGIN");
|
|
135
|
+
// Fetch entities
|
|
136
|
+
const session = await queryOne(`SELECT * FROM sessions WHERE id = $1`, [req.body.session_id || req.params.id]);
|
|
137
|
+
if (!session) {
|
|
138
|
+
return res.status(404).json({ error: { code: "NOT_FOUND", message: "session not found" } });
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// Preconditions
|
|
142
|
+
if (!(session?.state !== "deleted")) {
|
|
143
|
+
return res.status(422).json({ error: { code: "PRECONDITION_FAILED", message: "session.state != \\\"deleted\\\"" } });
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// Effects (applied in declaration order)
|
|
147
|
+
const __effect_0 = await query(`UPDATE sessions SET state = $1, updated_at = NOW() WHERE id = $2 RETURNING *`, ["deleted", req.body.session_id || req.params.id]);
|
|
148
|
+
if (!__effect_0 || __effect_0.length === 0) {
|
|
149
|
+
throw new Error("Effect failed: session.state = \"deleted\"");
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// Emit events
|
|
153
|
+
await eventBus.publish("SessionStateChanged", { session_id: session?.id, timestamp: new Date().toISOString(), actor_id: auth.actor_id }, "SessionService", auth.trace_id, __client);
|
|
154
|
+
|
|
155
|
+
res.json({ ok: true, action: "delete_session", entity: session });
|
|
156
|
+
await __client.query("COMMIT");
|
|
157
|
+
} catch (e: any) {
|
|
158
|
+
await __client.query("ROLLBACK");
|
|
159
|
+
res.status(400).json({ error: { code: "CAPABILITY_FAILED", message: e.message } });
|
|
160
|
+
} finally {
|
|
161
|
+
__client.release();
|
|
162
|
+
}
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
// CAPABILITY: add_message [transactional]
|
|
166
|
+
sessionsRouter.post("/add-message", __routeRateLimit, requireAuth, auditLog("add_message", "Session"), async (req: Request, res: Response) => {
|
|
167
|
+
const auth: AuthContext = (req as any).auth;
|
|
168
|
+
const __client = await pool.connect();
|
|
169
|
+
try {
|
|
170
|
+
await __client.query("BEGIN");
|
|
171
|
+
const { role, data } = req.body;
|
|
172
|
+
|
|
173
|
+
// Fetch entities
|
|
174
|
+
const session = await queryOne(`SELECT * FROM sessions WHERE id = $1`, [req.body.session_id || req.params.id]);
|
|
175
|
+
if (!session) {
|
|
176
|
+
return res.status(404).json({ error: { code: "NOT_FOUND", message: "session not found" } });
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// Preconditions
|
|
180
|
+
if (!([["active", "busy"]].flat().includes(session?.state))) {
|
|
181
|
+
return res.status(422).json({ error: { code: "PRECONDITION_FAILED", message: "session.state in [\\\"active\\\", \\\"busy\\\"]" } });
|
|
182
|
+
}
|
|
183
|
+
if (!([["user", "assistant", "system", "tool"]].flat().includes(role))) {
|
|
184
|
+
return res.status(422).json({ error: { code: "PRECONDITION_FAILED", message: "role in [\\\"user\\\", \\\"assistant\\\", \\\"system\\\", \\\"tool\\\"]" } });
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
// Emit events
|
|
188
|
+
await eventBus.publish("MessageAdded", { session_id: session?.id, timestamp: new Date().toISOString(), actor_id: auth.actor_id }, "SessionService", auth.trace_id, __client);
|
|
189
|
+
|
|
190
|
+
res.json({ ok: true, action: "add_message", entity: session });
|
|
191
|
+
await __client.query("COMMIT");
|
|
192
|
+
} catch (e: any) {
|
|
193
|
+
await __client.query("ROLLBACK");
|
|
194
|
+
res.status(400).json({ error: { code: "CAPABILITY_FAILED", message: e.message } });
|
|
195
|
+
} finally {
|
|
196
|
+
__client.release();
|
|
197
|
+
}
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
// CAPABILITY: update_part
|
|
201
|
+
sessionsRouter.post("/update-part", __routeRateLimit, requireAuth, auditLog("update_part", "Session"), async (req: Request, res: Response) => {
|
|
202
|
+
const auth: AuthContext = (req as any).auth;
|
|
203
|
+
try {
|
|
204
|
+
// sync: realtime — execute then broadcast to WebSocket channel
|
|
205
|
+
const { message_id, part_id, data } = req.body;
|
|
206
|
+
|
|
207
|
+
// Fetch entities
|
|
208
|
+
const session = await queryOne(`SELECT * FROM sessions WHERE id = $1`, [req.body.session_id || req.params.id]);
|
|
209
|
+
if (!session) {
|
|
210
|
+
return res.status(404).json({ error: { code: "NOT_FOUND", message: "session not found" } });
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
// Preconditions
|
|
214
|
+
if (!([["active", "busy"]].flat().includes(session?.state))) {
|
|
215
|
+
return res.status(422).json({ error: { code: "PRECONDITION_FAILED", message: "session.state in [\\\"active\\\", \\\"busy\\\"]" } });
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
// Emit events
|
|
219
|
+
await eventBus.publish("PartUpdated", { session_id: session?.id, timestamp: new Date().toISOString(), actor_id: auth.actor_id }, "SessionService", auth.trace_id);
|
|
220
|
+
|
|
221
|
+
res.json({ ok: true, action: "update_part", entity: session });
|
|
222
|
+
// Broadcast to WebSocket subscribers after successful execution
|
|
223
|
+
const { broadcastToChannel: _broadcast } = require("../websocket") as any;
|
|
224
|
+
if (typeof _broadcast === "function") {
|
|
225
|
+
_broadcast("SessionService", { type: "update_part", payload: req.body, actor: auth.actor_id });
|
|
226
|
+
}
|
|
227
|
+
} catch (e: any) {
|
|
228
|
+
res.status(400).json({ error: { code: "CAPABILITY_FAILED", message: e.message } });
|
|
229
|
+
}
|
|
230
|
+
});
|
|
231
|
+
|
|
232
|
+
// CAPABILITY: compact_session [transactional]
|
|
233
|
+
sessionsRouter.post("/compact-session", __routeRateLimit, requireAuth, auditLog("compact_session", "Session"), async (req: Request, res: Response) => {
|
|
234
|
+
const auth: AuthContext = (req as any).auth;
|
|
235
|
+
const __client = await pool.connect();
|
|
236
|
+
try {
|
|
237
|
+
await __client.query("BEGIN");
|
|
238
|
+
// Fetch entities
|
|
239
|
+
const session = await queryOne(`SELECT * FROM sessions WHERE id = $1`, [req.body.session_id || req.params.id]);
|
|
240
|
+
if (!session) {
|
|
241
|
+
return res.status(404).json({ error: { code: "NOT_FOUND", message: "session not found" } });
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
// Preconditions
|
|
245
|
+
if (!(session?.state === "active")) {
|
|
246
|
+
return res.status(422).json({ error: { code: "PRECONDITION_FAILED", message: "session.state == \\\"active\\\"" } });
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
// Effects (applied in declaration order)
|
|
250
|
+
const __effect_0 = await query(`UPDATE sessions SET state = $1, updated_at = NOW() WHERE id = $2 RETURNING *`, ["compacting", req.body.session_id || req.params.id]);
|
|
251
|
+
if (!__effect_0 || __effect_0.length === 0) {
|
|
252
|
+
throw new Error("Effect failed: session.state = \"compacting\"");
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
// Emit events
|
|
256
|
+
await eventBus.publish("SessionStateChanged", { session_id: session?.id, timestamp: new Date().toISOString(), actor_id: auth.actor_id }, "SessionService", auth.trace_id, __client);
|
|
257
|
+
|
|
258
|
+
res.json({ ok: true, action: "compact_session", entity: session });
|
|
259
|
+
await __client.query("COMMIT");
|
|
260
|
+
} catch (e: any) {
|
|
261
|
+
await __client.query("ROLLBACK");
|
|
262
|
+
res.status(400).json({ error: { code: "CAPABILITY_FAILED", message: e.message } });
|
|
263
|
+
} finally {
|
|
264
|
+
__client.release();
|
|
265
|
+
}
|
|
266
|
+
});
|
|
267
|
+
|
|
268
|
+
// RELATION: messages (has_many Message)
|
|
269
|
+
sessionsRouter.get("/:id/messages", requireAuth, async (req: Request, res: Response) => {
|
|
270
|
+
try {
|
|
271
|
+
const page = parseInt(req.query.page as string) || 1;
|
|
272
|
+
const pageSize = Math.min(parseInt(req.query.page_size as string) || 50, 100);
|
|
273
|
+
const offset = (page - 1) * pageSize;
|
|
274
|
+
const rows = await query(`SELECT * FROM messages WHERE session_id = $1 ORDER BY created_at DESC LIMIT $2 OFFSET $3`, [req.params.id, pageSize, offset]);
|
|
275
|
+
const [{ count }] = await query(`SELECT COUNT(*) as count FROM messages WHERE session_id = $1`, [req.params.id]);
|
|
276
|
+
res.json({ items: rows, total: parseInt(count), page, page_size: pageSize });
|
|
277
|
+
} catch (e: any) {
|
|
278
|
+
res.status(500).json({ error: { code: "DB_ERROR", message: e.message } });
|
|
279
|
+
}
|
|
280
|
+
});
|
|
281
|
+
|
|
282
|
+
// RELATION: tool_calls (has_many ToolCall)
|
|
283
|
+
sessionsRouter.get("/:id/tool_calls", requireAuth, async (req: Request, res: Response) => {
|
|
284
|
+
try {
|
|
285
|
+
const page = parseInt(req.query.page as string) || 1;
|
|
286
|
+
const pageSize = Math.min(parseInt(req.query.page_size as string) || 50, 100);
|
|
287
|
+
const offset = (page - 1) * pageSize;
|
|
288
|
+
const rows = await query(`SELECT * FROM tool_calls WHERE session_id = $1 ORDER BY created_at DESC LIMIT $2 OFFSET $3`, [req.params.id, pageSize, offset]);
|
|
289
|
+
const [{ count }] = await query(`SELECT COUNT(*) as count FROM tool_calls WHERE session_id = $1`, [req.params.id]);
|
|
290
|
+
res.json({ items: rows, total: parseInt(count), page, page_size: pageSize });
|
|
291
|
+
} catch (e: any) {
|
|
292
|
+
res.status(500).json({ error: { code: "DB_ERROR", message: e.message } });
|
|
293
|
+
}
|
|
294
|
+
});
|