jishushell 0.6.18 → 0.7.3
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/apps/anythingllm-container.yaml +1 -0
- package/apps/browserless-chromium-container.yaml +1 -0
- package/apps/filebrowser-container.yaml +1 -0
- package/apps/hermes-container.yaml +1 -7
- package/apps/immich-container-lite.yaml +337 -0
- package/apps/immich-container.yaml +371 -0
- package/apps/jishu-kb-container.yaml +26 -21
- package/apps/ollama-binary.yaml +1 -0
- package/apps/ollama-cpu-container.yaml +1 -0
- package/apps/ollama-with-hollama-binary.yaml +2 -0
- package/apps/openclaw-binary.yaml +4 -8
- package/apps/openclaw-container.yaml +1 -7
- package/apps/openclaw-with-ollama-container.yaml +1 -0
- package/apps/openclaw-with-searxng-container.yaml +20 -0
- package/apps/searxng-container.yaml +20 -0
- package/apps/weknora-container.yaml +5 -0
- package/dependencies/jishushell-panel-0.7.3.tgz +0 -0
- package/dist/cli/core.js +1 -1
- package/dist/cli/core.js.map +1 -1
- package/dist/cli/doctor.js +96 -0
- package/dist/cli/doctor.js.map +1 -1
- package/dist/config.d.ts +9 -1
- package/dist/config.js +72 -2
- package/dist/config.js.map +1 -1
- package/dist/install.js +60 -19
- package/dist/install.js.map +1 -1
- package/dist/routes/admin.d.ts +2 -0
- package/dist/routes/admin.js +72 -0
- package/dist/routes/admin.js.map +1 -0
- package/dist/routes/docker.d.ts +2 -0
- package/dist/routes/docker.js +58 -0
- package/dist/routes/docker.js.map +1 -0
- package/dist/routes/file-mounts.js +5 -8
- package/dist/routes/file-mounts.js.map +1 -1
- package/dist/routes/instances.d.ts +0 -14
- package/dist/routes/instances.js +44 -1184
- package/dist/routes/instances.js.map +1 -1
- package/dist/server.d.ts +6 -0
- package/dist/server.js +53 -20
- package/dist/server.js.map +1 -1
- package/dist/services/app-common/catalog-service.js +15 -5
- package/dist/services/app-common/catalog-service.js.map +1 -1
- package/dist/services/app-common/delete-service.js +5 -0
- package/dist/services/app-common/delete-service.js.map +1 -1
- package/dist/services/app-common/instance-store.js +3 -0
- package/dist/services/app-common/instance-store.js.map +1 -1
- package/dist/services/app-common/lifecycle-service.js +12 -4
- package/dist/services/app-common/lifecycle-service.js.map +1 -1
- package/dist/services/app-common/ownership.d.ts +3 -0
- package/dist/services/app-common/ownership.js +11 -0
- package/dist/services/app-common/ownership.js.map +1 -0
- package/dist/services/app-common/runtime-facts.js +2 -0
- package/dist/services/app-common/runtime-facts.js.map +1 -1
- package/dist/services/app-common/spec-materializer.d.ts +0 -1
- package/dist/services/app-common/spec-materializer.js +21 -87
- package/dist/services/app-common/spec-materializer.js.map +1 -1
- package/dist/services/app-common/status-refresh.js +25 -13
- package/dist/services/app-common/status-refresh.js.map +1 -1
- package/dist/services/app-modules/browserless/routes.js +5 -3
- package/dist/services/app-modules/browserless/routes.js.map +1 -1
- package/dist/services/capabilities/contract.d.ts +1 -2
- package/dist/services/capabilities/contract.js +0 -10
- package/dist/services/capabilities/contract.js.map +1 -1
- package/dist/services/capabilities/endpoint-validator.js +0 -1
- package/dist/services/capabilities/endpoint-validator.js.map +1 -1
- package/dist/services/capabilities/health.js +1 -1
- package/dist/services/capabilities/health.js.map +1 -1
- package/dist/services/capability-proxy/http.d.ts +7 -0
- package/dist/services/capability-proxy/http.js +555 -0
- package/dist/services/capability-proxy/http.js.map +1 -0
- package/dist/services/capability-proxy/terminal.d.ts +4 -0
- package/dist/services/capability-proxy/terminal.js +179 -0
- package/dist/services/capability-proxy/terminal.js.map +1 -0
- package/dist/services/connections/admin.js +19 -9
- package/dist/services/connections/admin.js.map +1 -1
- package/dist/services/connections/apply.d.ts +3 -9
- package/dist/services/connections/apply.js +0 -29
- package/dist/services/connections/apply.js.map +1 -1
- package/dist/services/connections/transactor.js +2 -2
- package/dist/services/connections/transactor.js.map +1 -1
- package/dist/services/files/bootstrap.d.ts +7 -0
- package/dist/services/files/bootstrap.js +16 -0
- package/dist/services/files/bootstrap.js.map +1 -0
- package/dist/services/files/photos/upload-page.d.ts +2 -0
- package/dist/services/files/photos/upload-page.js +248 -0
- package/dist/services/files/photos/upload-page.js.map +1 -0
- package/dist/services/files/photos/upload-store.d.ts +74 -0
- package/dist/services/files/photos/upload-store.js +432 -0
- package/dist/services/files/photos/upload-store.js.map +1 -0
- package/dist/services/http/proxy-utils.d.ts +7 -0
- package/dist/services/http/proxy-utils.js +29 -0
- package/dist/services/http/proxy-utils.js.map +1 -0
- package/dist/services/http/request-utils.d.ts +3 -0
- package/dist/services/http/request-utils.js +23 -0
- package/dist/services/http/request-utils.js.map +1 -0
- package/dist/services/instances/manager.d.ts +6 -5
- package/dist/services/instances/manager.js +45 -51
- package/dist/services/instances/manager.js.map +1 -1
- package/dist/services/instances/pairing.d.ts +17 -0
- package/dist/services/instances/pairing.js +53 -0
- package/dist/services/instances/pairing.js.map +1 -0
- package/dist/services/instances/status.d.ts +2 -0
- package/dist/services/instances/status.js +11 -0
- package/dist/services/instances/status.js.map +1 -0
- package/dist/services/integrations/hermes/integration.d.ts +1 -1
- package/dist/services/integrations/hermes/integration.js +7 -8
- package/dist/services/integrations/hermes/integration.js.map +1 -1
- package/dist/services/integrations/immich/client.d.ts +93 -0
- package/dist/services/integrations/immich/client.js +458 -0
- package/dist/services/integrations/immich/client.js.map +1 -0
- package/dist/services/integrations/immich/config.d.ts +15 -0
- package/dist/services/integrations/immich/config.js +178 -0
- package/dist/services/integrations/immich/config.js.map +1 -0
- package/dist/services/integrations/immich/discovery.d.ts +9 -0
- package/dist/services/integrations/immich/discovery.js +101 -0
- package/dist/services/integrations/immich/discovery.js.map +1 -0
- package/dist/services/integrations/immich/gallery-renderer.d.ts +5 -0
- package/dist/services/integrations/immich/gallery-renderer.js +150 -0
- package/dist/services/integrations/immich/gallery-renderer.js.map +1 -0
- package/dist/services/integrations/immich/immich-shim.d.ts +11 -0
- package/dist/services/integrations/immich/immich-shim.js +439 -0
- package/dist/services/integrations/immich/immich-shim.js.map +1 -0
- package/dist/services/integrations/immich/integration.d.ts +18 -0
- package/dist/services/integrations/immich/integration.js +64 -0
- package/dist/services/integrations/immich/integration.js.map +1 -0
- package/dist/services/integrations/immich/photo-library.d.ts +4 -0
- package/dist/services/integrations/immich/photo-library.js +63 -0
- package/dist/services/integrations/immich/photo-library.js.map +1 -0
- package/dist/services/integrations/immich/review-executor.d.ts +3 -0
- package/dist/services/integrations/immich/review-executor.js +41 -0
- package/dist/services/integrations/immich/review-executor.js.map +1 -0
- package/dist/services/integrations/immich/review-session-service.d.ts +27 -0
- package/dist/services/integrations/immich/review-session-service.js +206 -0
- package/dist/services/integrations/immich/review-session-service.js.map +1 -0
- package/dist/services/integrations/immich/review-store.d.ts +47 -0
- package/dist/services/integrations/immich/review-store.js +347 -0
- package/dist/services/integrations/immich/review-store.js.map +1 -0
- package/dist/services/integrations/immich/routes.d.ts +7 -0
- package/dist/services/integrations/immich/routes.js +363 -0
- package/dist/services/integrations/immich/routes.js.map +1 -0
- package/dist/services/integrations/immich/types.d.ts +186 -0
- package/dist/services/integrations/immich/types.js +2 -0
- package/dist/services/integrations/immich/types.js.map +1 -0
- package/dist/services/integrations/index.d.ts +1 -0
- package/dist/services/integrations/index.js +1 -0
- package/dist/services/integrations/index.js.map +1 -1
- package/dist/services/integrations/installable/installers/integration.js +113 -7
- package/dist/services/integrations/installable/installers/integration.js.map +1 -1
- package/dist/services/integrations/jishukb/integration.d.ts +3 -1
- package/dist/services/integrations/jishukb/integration.js +121 -10
- package/dist/services/integrations/jishukb/integration.js.map +1 -1
- package/dist/services/integrations/openclaw/integration.d.ts +21 -7
- package/dist/services/integrations/openclaw/integration.js +385 -158
- package/dist/services/integrations/openclaw/integration.js.map +1 -1
- package/dist/services/integrations/openclaw/jishukb-native-mcp.d.ts +58 -0
- package/dist/services/integrations/openclaw/jishukb-native-mcp.js +373 -0
- package/dist/services/integrations/openclaw/jishukb-native-mcp.js.map +1 -0
- package/dist/services/integrations/openclaw/jishukb-shim.d.ts +8 -4
- package/dist/services/integrations/openclaw/jishukb-shim.js +624 -17
- package/dist/services/integrations/openclaw/jishukb-shim.js.map +1 -1
- package/dist/services/integrations/openclaw/mcporter.d.ts +13 -0
- package/dist/services/integrations/openclaw/mcporter.js +31 -0
- package/dist/services/integrations/openclaw/mcporter.js.map +1 -1
- package/dist/services/integrations/openclaw/native-mcp.d.ts +48 -0
- package/dist/services/integrations/openclaw/native-mcp.js +125 -0
- package/dist/services/integrations/openclaw/native-mcp.js.map +1 -0
- package/dist/services/integrations/openclaw/routes.js +4 -1
- package/dist/services/integrations/openclaw/routes.js.map +1 -1
- package/dist/services/integrations/types.d.ts +5 -17
- package/dist/services/repair/runtime-repair.js +68 -1
- package/dist/services/repair/runtime-repair.js.map +1 -1
- package/dist/services/runtime/docker-network.d.ts +8 -0
- package/dist/services/runtime/docker-network.js +123 -0
- package/dist/services/runtime/docker-network.js.map +1 -0
- package/dist/services/runtime/driver-registry.d.ts +4 -0
- package/dist/services/runtime/driver-registry.js.map +1 -1
- package/dist/services/runtime/drivers/nomad.d.ts +1 -0
- package/dist/services/runtime/drivers/nomad.js +35 -5
- package/dist/services/runtime/drivers/nomad.js.map +1 -1
- package/dist/services/runtime/service-manager.d.ts +2 -0
- package/dist/services/runtime/service-manager.js +18 -0
- package/dist/services/runtime/service-manager.js.map +1 -0
- package/dist/services/runtime/types.d.ts +1 -0
- package/dist/services/runtime/workload-compiler.js +29 -4
- package/dist/services/runtime/workload-compiler.js.map +1 -1
- package/dist/services/setup/setup-manager.js +29 -73
- package/dist/services/setup/setup-manager.js.map +1 -1
- package/dist/services/system/runtime-ownership.d.ts +36 -0
- package/dist/services/system/runtime-ownership.js +250 -0
- package/dist/services/system/runtime-ownership.js.map +1 -0
- package/dist/services/system/system-reconciler.js +53 -0
- package/dist/services/system/system-reconciler.js.map +1 -1
- package/dist/types.d.ts +19 -3
- package/dist/utils/path-safety.js +1 -1
- package/dist/utils/service-user.d.ts +13 -0
- package/dist/utils/service-user.js +129 -0
- package/dist/utils/service-user.js.map +1 -0
- package/install/jishu-install.sh +0 -1
- package/node_modules/brace-expansion/dist/commonjs/index.js +24 -14
- package/node_modules/brace-expansion/dist/commonjs/index.js.map +1 -1
- package/node_modules/brace-expansion/dist/esm/index.js +24 -14
- package/node_modules/brace-expansion/dist/esm/index.js.map +1 -1
- package/node_modules/brace-expansion/package.json +2 -2
- package/node_modules/fast-uri/index.js +1 -1
- package/node_modules/fast-uri/package.json +1 -1
- package/node_modules/fast-uri/test/security.test.js +28 -0
- package/node_modules/fastify/SECURITY.md +1 -1
- package/node_modules/fastify/SPONSORS.md +6 -4
- package/node_modules/fastify/docs/Guides/Database.md +0 -28
- package/node_modules/fastify/docs/Guides/Ecosystem.md +13 -2
- package/node_modules/fastify/docs/Guides/Serverless.md +2 -2
- package/node_modules/fastify/docs/Guides/Write-Plugin.md +1 -1
- package/node_modules/fastify/docs/Reference/Encapsulation.md +27 -26
- package/node_modules/fastify/docs/Reference/Errors.md +10 -4
- package/node_modules/fastify/docs/Reference/HTTP2.md +10 -10
- package/node_modules/fastify/docs/Reference/Hooks.md +4 -4
- package/node_modules/fastify/docs/Reference/Index.md +14 -16
- package/node_modules/fastify/docs/Reference/LTS.md +12 -13
- package/node_modules/fastify/docs/Reference/Lifecycle.md +9 -8
- package/node_modules/fastify/docs/Reference/Logging.md +44 -39
- package/node_modules/fastify/docs/Reference/Middleware.md +21 -25
- package/node_modules/fastify/docs/Reference/Principles.md +2 -2
- package/node_modules/fastify/docs/Reference/Reply.md +6 -1
- package/node_modules/fastify/docs/Reference/Request.md +27 -16
- package/node_modules/fastify/docs/Reference/Routes.md +5 -2
- package/node_modules/fastify/docs/Reference/Server.md +31 -3
- package/node_modules/fastify/docs/Reference/Type-Providers.md +29 -5
- package/node_modules/fastify/docs/Reference/Validation-and-Serialization.md +15 -2
- package/node_modules/fastify/docs/Reference/Warnings.md +7 -6
- package/node_modules/fastify/eslint.config.js +7 -2
- package/node_modules/fastify/fastify.d.ts +8 -3
- package/node_modules/fastify/fastify.js +43 -14
- package/node_modules/fastify/lib/content-type-parser.js +13 -1
- package/node_modules/fastify/lib/decorate.js +11 -3
- package/node_modules/fastify/lib/error-handler.js +4 -3
- package/node_modules/fastify/lib/error-serializer.js +59 -59
- package/node_modules/fastify/lib/errors.js +16 -1
- package/node_modules/fastify/lib/four-oh-four.js +14 -9
- package/node_modules/fastify/lib/handle-request.js +11 -5
- package/node_modules/fastify/lib/plugin-override.js +2 -1
- package/node_modules/fastify/lib/plugin-utils.js +5 -5
- package/node_modules/fastify/lib/reply.js +63 -8
- package/node_modules/fastify/lib/request.js +14 -4
- package/node_modules/fastify/lib/route.js +20 -6
- package/node_modules/fastify/lib/schema-controller.js +1 -1
- package/node_modules/fastify/lib/schemas.js +37 -30
- package/node_modules/fastify/lib/symbols.js +3 -1
- package/node_modules/fastify/lib/validation.js +1 -13
- package/node_modules/fastify/lib/warnings.js +3 -3
- package/node_modules/fastify/package.json +13 -15
- package/node_modules/fastify/scripts/validate-ecosystem-links.js +1 -0
- package/node_modules/fastify/test/bundler/esbuild/package.json +1 -1
- package/node_modules/fastify/test/close-pipelining.test.js +1 -2
- package/node_modules/fastify/test/custom-http-server.test.js +38 -0
- package/node_modules/fastify/test/decorator-instance-properties.test.js +63 -0
- package/node_modules/fastify/test/diagnostics-channel/async-error-handler.test.js +74 -0
- package/node_modules/fastify/test/hooks.test.js +23 -0
- package/node_modules/fastify/test/http-methods/get.test.js +1 -1
- package/node_modules/fastify/test/http2/plain.test.js +135 -0
- package/node_modules/fastify/test/http2/secure-with-fallback.test.js +1 -1
- package/node_modules/fastify/test/https/https.test.js +1 -2
- package/node_modules/fastify/test/internals/errors.test.js +31 -1
- package/node_modules/fastify/test/internals/plugin.test.js +3 -1
- package/node_modules/fastify/test/internals/request.test.js +27 -3
- package/node_modules/fastify/test/internals/schema-controller-perf.test.js +33 -0
- package/node_modules/fastify/test/logger/logging.test.js +18 -1
- package/node_modules/fastify/test/logger/options.test.js +38 -1
- package/node_modules/fastify/test/reply-error.test.js +1 -1
- package/node_modules/fastify/test/reply-trailers.test.js +70 -0
- package/node_modules/fastify/test/request-media-type.test.js +105 -0
- package/node_modules/fastify/test/route-prefix.test.js +34 -0
- package/node_modules/fastify/test/router-options.test.js +222 -11
- package/node_modules/fastify/test/schema-serialization.test.js +108 -0
- package/node_modules/fastify/test/schema-validation.test.js +24 -0
- package/node_modules/fastify/test/scripts/validate-ecosystem-links.test.js +40 -57
- package/node_modules/fastify/test/throw.test.js +14 -0
- package/node_modules/fastify/test/trust-proxy.test.js +21 -0
- package/node_modules/fastify/test/types/content-type-parser.tst.ts +70 -0
- package/node_modules/fastify/test/types/{decorate-request-reply.test-d.ts → decorate-request-reply.tst.ts} +4 -4
- package/node_modules/fastify/test/types/{dummy-plugin.ts → dummy-plugin.mts} +1 -1
- package/node_modules/fastify/test/types/errors.tst.ts +91 -0
- package/node_modules/fastify/test/types/fastify.tst.ts +351 -0
- package/node_modules/fastify/test/types/hooks.tst.ts +578 -0
- package/node_modules/fastify/test/types/instance.tst.ts +597 -0
- package/node_modules/fastify/test/types/{logger.test-d.ts → logger.tst.ts} +61 -62
- package/node_modules/fastify/test/types/plugin.tst.ts +96 -0
- package/node_modules/fastify/test/types/register.tst.ts +245 -0
- package/node_modules/fastify/test/types/reply.tst.ts +297 -0
- package/node_modules/fastify/test/types/request.tst.ts +199 -0
- package/node_modules/fastify/test/types/route.tst.ts +576 -0
- package/node_modules/fastify/test/types/{schema.test-d.ts → schema.tst.ts} +22 -22
- package/node_modules/fastify/test/types/{serverFactory.test-d.ts → serverFactory.tst.ts} +4 -4
- package/node_modules/fastify/test/types/tsconfig.json +9 -0
- package/node_modules/fastify/test/types/{type-provider.test-d.ts → type-provider.tst.ts} +256 -250
- package/node_modules/fastify/test/types/using.tst.ts +14 -0
- package/node_modules/fastify/types/errors.d.ts +3 -0
- package/node_modules/fastify/types/request.d.ts +23 -2
- package/node_modules/jishushell-panel/output/public/assets/{ApiKeyField-NKcbHjNz.js → ApiKeyField-Ce5d1xna.js} +1 -1
- package/node_modules/jishushell-panel/output/public/assets/{Dashboard-Da1fL38t.js → Dashboard-BXame3yg.js} +1 -1
- package/node_modules/jishushell-panel/output/public/assets/{HermesChatPanel-DZvmYsoh.js → HermesChatPanel-BHZtPCJd.js} +1 -1
- package/node_modules/jishushell-panel/output/public/assets/{HermesConfigForm-BLUWlKwm.js → HermesConfigForm-CB3GbNX9.js} +1 -1
- package/node_modules/jishushell-panel/output/public/assets/{InitPassword-BAKsshzk.js → InitPassword-Boab9F6g.js} +1 -1
- package/node_modules/jishushell-panel/output/public/assets/InstanceDetail-DrIWCqo-.js +14 -0
- package/node_modules/jishushell-panel/output/public/assets/{Login-DHeOmwI8.js → Login-CzpOkNau.js} +1 -1
- package/node_modules/jishushell-panel/output/public/assets/NewInstance-CANXyCcL.js +1 -0
- package/node_modules/jishushell-panel/output/public/assets/{ProviderRecommendations-H0ByEYF0.js → ProviderRecommendations-BABo9VOC.js} +1 -1
- package/node_modules/jishushell-panel/output/public/assets/Settings-CKp5XxFh.js +1 -0
- package/node_modules/jishushell-panel/output/public/assets/Setup-C7xVDPow.js +1 -0
- package/node_modules/jishushell-panel/output/public/assets/{WeixinLoginPanel-D-T6BxkQ.js → WeixinLoginPanel-B765Xz4C.js} +1 -1
- package/node_modules/jishushell-panel/output/public/assets/{index-ERt6_ngA.js → index-Bs6DSbiR.js} +6 -6
- package/node_modules/jishushell-panel/output/public/assets/{registry-DF93EzIb.js → registry-sWIZsIEF.js} +2 -2
- package/node_modules/jishushell-panel/output/public/assets/{usePolling-DeoThIQn.js → usePolling-D4IDOQd_.js} +1 -1
- package/node_modules/jishushell-panel/output/public/assets/vendor-i18n-Df8aUdv8.js +1 -0
- package/node_modules/jishushell-panel/output/public/assets/{vendor-react-Cc84NArf.js → vendor-react-0L0rjmYG.js} +3 -3
- package/node_modules/jishushell-panel/output/public/index.html +3 -3
- package/node_modules/jishushell-panel/package.json +1 -1
- package/node_modules/semver/classes/range.js +6 -2
- package/node_modules/semver/package.json +1 -1
- package/package.json +4 -4
- package/scripts/check-app-spec.mjs +4 -12
- package/scripts/check-architecture-boundaries.mjs +178 -0
- package/scripts/pack-gui-and-send-pi.sh +5 -3
- package/dependencies/jishushell-panel-0.6.18.tgz +0 -0
- package/dist/services/connections/suggestions.d.ts +0 -27
- package/dist/services/connections/suggestions.js +0 -124
- package/dist/services/connections/suggestions.js.map +0 -1
- package/node_modules/fastify/test/types/content-type-parser.test-d.ts +0 -72
- package/node_modules/fastify/test/types/errors.test-d.ts +0 -90
- package/node_modules/fastify/test/types/fastify.test-d.ts +0 -352
- package/node_modules/fastify/test/types/hooks.test-d.ts +0 -550
- package/node_modules/fastify/test/types/import.ts +0 -2
- package/node_modules/fastify/test/types/instance.test-d.ts +0 -588
- package/node_modules/fastify/test/types/plugin.test-d.ts +0 -97
- package/node_modules/fastify/test/types/register.test-d.ts +0 -237
- package/node_modules/fastify/test/types/reply.test-d.ts +0 -254
- package/node_modules/fastify/test/types/request.test-d.ts +0 -188
- package/node_modules/fastify/test/types/route.test-d.ts +0 -553
- package/node_modules/fastify/test/types/using.test-d.ts +0 -17
- package/node_modules/jishushell-panel/output/public/assets/InstanceDetail-Dgyc_TX5.js +0 -14
- package/node_modules/jishushell-panel/output/public/assets/NewInstance-CIy0cYtp.js +0 -1
- package/node_modules/jishushell-panel/output/public/assets/Settings-DAT-UMfP.js +0 -1
- package/node_modules/jishushell-panel/output/public/assets/Setup-g3uckFYR.js +0 -1
- package/node_modules/jishushell-panel/output/public/assets/vendor-i18n-CS8DFbkQ.js +0 -1
|
@@ -9,9 +9,11 @@
|
|
|
9
9
|
*
|
|
10
10
|
* Scope intentionally stays typed and bounded:
|
|
11
11
|
* - Read/search: list KBs, search, list documents, read handbook, read
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
* -
|
|
12
|
+
* document metadata/source/chunks/FAQ, inspect ingest jobs, and read
|
|
13
|
+
* sanitized config/capabilities
|
|
14
|
+
* - Write: create KBs, upload documents, import URLs, retry jobs, and
|
|
15
|
+
* reindex documents in a chosen KB
|
|
16
|
+
* - Dangerous delete/cancel/reindex operations require explicit confirmation arguments
|
|
15
17
|
* - No raw admin/provider passthrough: secrets and arbitrary provider edits
|
|
16
18
|
* remain outside the agent surface
|
|
17
19
|
*
|
|
@@ -26,7 +28,7 @@
|
|
|
26
28
|
* Stdio framing: NDJSON JSON-RPC 2.0 (MCP standard). Pure Node builtins, no
|
|
27
29
|
* npm install needed inside the runtime image.
|
|
28
30
|
*/
|
|
29
|
-
export const JISHUKB_MCP_SHIM_VERSION = "0.
|
|
31
|
+
export const JISHUKB_MCP_SHIM_VERSION = "0.3.0";
|
|
30
32
|
/** Default topK when the caller doesn't specify one. Mirrors the manifest
|
|
31
33
|
* `JISHU_KB_TOPK` default so the agent and the backend agree on page size. */
|
|
32
34
|
export const JISHUKB_DEFAULT_TOPK = 6;
|
|
@@ -34,6 +36,8 @@ export const JISHUKB_DEFAULT_TOPK = 6;
|
|
|
34
36
|
export const JISHUKB_FETCH_TIMEOUT_MS = 60_000;
|
|
35
37
|
/** Soft guard for upload memory use. */
|
|
36
38
|
export const JISHUKB_MAX_UPLOAD_BYTES = 30 * 1024 * 1024;
|
|
39
|
+
/** Soft guard for text returned through MCP. */
|
|
40
|
+
export const JISHUKB_MAX_TEXT_RESPONSE_CHARS = 12_000;
|
|
37
41
|
export const JISHUKB_MCP_SHIM_SOURCE = `#!/usr/bin/env node
|
|
38
42
|
// jishushell-jishukb-shim — generated, do not edit by hand.
|
|
39
43
|
// Source: src/services/integrations/openclaw/jishukb-shim.ts
|
|
@@ -44,6 +48,7 @@ const ALLOWED_UPLOAD_ROOTS_LIT = "__JS_ALLOWED_UPLOAD_ROOTS__";
|
|
|
44
48
|
|
|
45
49
|
const fs = require("node:fs");
|
|
46
50
|
const path = require("node:path");
|
|
51
|
+
const { TextDecoder } = require("node:util");
|
|
47
52
|
|
|
48
53
|
const BASE_URL = (BASE_URL_LIT.startsWith("__JS_") ? (process.env.JISHUKB_BASE_URL || "") : BASE_URL_LIT).replace(/\\/+$/, "");
|
|
49
54
|
const KB_ID = KB_ID_LIT.startsWith("__JS_") ? trimString(process.env.JISHUKB_KB_ID || "") : trimString(KB_ID_LIT);
|
|
@@ -55,6 +60,7 @@ const ALLOWED_UPLOAD_ROOTS = (
|
|
|
55
60
|
const DEFAULT_TOPK = ${JISHUKB_DEFAULT_TOPK};
|
|
56
61
|
const FETCH_TIMEOUT = ${JISHUKB_FETCH_TIMEOUT_MS};
|
|
57
62
|
const MAX_UPLOAD_BYTES = ${JISHUKB_MAX_UPLOAD_BYTES};
|
|
63
|
+
const MAX_TEXT_RESPONSE_CHARS = ${JISHUKB_MAX_TEXT_RESPONSE_CHARS};
|
|
58
64
|
const OPEN_UPLOAD_FLAGS = fs.constants.O_RDONLY
|
|
59
65
|
| (typeof fs.constants.O_NOFOLLOW === "number" ? fs.constants.O_NOFOLLOW : 0)
|
|
60
66
|
| (typeof fs.constants.O_NONBLOCK === "number" ? fs.constants.O_NONBLOCK : 0);
|
|
@@ -66,7 +72,9 @@ function envCheck() {
|
|
|
66
72
|
}
|
|
67
73
|
|
|
68
74
|
function trimString(raw) {
|
|
69
|
-
|
|
75
|
+
if (typeof raw === "string") return raw.trim();
|
|
76
|
+
if (typeof raw === "number" || typeof raw === "boolean") return String(raw).trim();
|
|
77
|
+
return "";
|
|
70
78
|
}
|
|
71
79
|
|
|
72
80
|
function jsonText(value) {
|
|
@@ -247,6 +255,205 @@ async function readText(toolName, relativePath, options) {
|
|
|
247
255
|
return await res.text();
|
|
248
256
|
}
|
|
249
257
|
|
|
258
|
+
function cappedText(raw, maxChars) {
|
|
259
|
+
const text = String(raw ?? "");
|
|
260
|
+
if (text.length <= maxChars) {
|
|
261
|
+
return { text, truncated: false, characters: text.length };
|
|
262
|
+
}
|
|
263
|
+
return {
|
|
264
|
+
text: text.slice(0, Math.max(0, maxChars - 1)) + "…",
|
|
265
|
+
truncated: true,
|
|
266
|
+
characters: text.length,
|
|
267
|
+
};
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
function optionalString(raw) {
|
|
271
|
+
const value = trimString(raw);
|
|
272
|
+
return value || null;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
function positiveInt(raw, fallback, max) {
|
|
276
|
+
const n = Number(raw);
|
|
277
|
+
if (!Number.isFinite(n)) return fallback;
|
|
278
|
+
const i = Math.floor(n);
|
|
279
|
+
if (i < 1) return fallback;
|
|
280
|
+
return Math.min(i, max);
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
function boolWithDefault(raw, fallback) {
|
|
284
|
+
if (raw === undefined || raw === null || raw === "") return fallback;
|
|
285
|
+
if (typeof raw === "boolean") return raw;
|
|
286
|
+
const text = trimString(raw).toLowerCase();
|
|
287
|
+
if (["1", "true", "yes", "y"].includes(text)) return true;
|
|
288
|
+
if (["0", "false", "no", "n"].includes(text)) return false;
|
|
289
|
+
return fallback;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
function appendOptionalQuery(qs, key, value) {
|
|
293
|
+
const text = trimString(value);
|
|
294
|
+
if (text) qs.set(key, text);
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
function encodePathPart(value) {
|
|
298
|
+
return encodeURIComponent(value);
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
function normalizeBacklinks(raw) {
|
|
302
|
+
return Array.isArray(raw) ? raw : [];
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
function normalizeDocument(item, kbId) {
|
|
306
|
+
const doc = item && typeof item === "object" ? item : {};
|
|
307
|
+
return {
|
|
308
|
+
id: doc.id || null,
|
|
309
|
+
kbId: doc.kb_id || doc.kbId || kbId || null,
|
|
310
|
+
title: doc.title || null,
|
|
311
|
+
relPath: doc.rel_path || doc.relPath || null,
|
|
312
|
+
mime: doc.mime || null,
|
|
313
|
+
sha256: doc.sha256 || null,
|
|
314
|
+
bytes: doc.bytes ?? null,
|
|
315
|
+
status: doc.status || null,
|
|
316
|
+
createdAt: doc.created_at ?? doc.createdAt ?? null,
|
|
317
|
+
origin: doc.origin || null,
|
|
318
|
+
sourcePath: doc.source_path || doc.sourcePath || null,
|
|
319
|
+
sourceUrl: doc.source_url || doc.sourceUrl || null,
|
|
320
|
+
batchId: doc.batch_id || doc.batchId || null,
|
|
321
|
+
clientItemId: doc.client_item_id || doc.clientItemId || null,
|
|
322
|
+
externalAssetId: doc.external_asset_id || doc.externalAssetId || null,
|
|
323
|
+
backlinks: normalizeBacklinks(doc.backlinks),
|
|
324
|
+
chunkCount: doc.chunkCount ?? null,
|
|
325
|
+
faqCount: doc.faqCount ?? null,
|
|
326
|
+
jobCount: doc.jobCount ?? null,
|
|
327
|
+
};
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
function normalizeJob(item, kbId) {
|
|
331
|
+
const job = item && typeof item === "object" ? item : {};
|
|
332
|
+
return {
|
|
333
|
+
id: job.id || null,
|
|
334
|
+
docId: job.docId || job.doc_id || null,
|
|
335
|
+
kbId: job.kbId || job.kb_id || kbId || null,
|
|
336
|
+
filename: job.filename || null,
|
|
337
|
+
relPath: job.relPath || job.rel_path || null,
|
|
338
|
+
mime: job.mime || null,
|
|
339
|
+
sha256: job.sha256 || null,
|
|
340
|
+
bytes: job.bytes ?? null,
|
|
341
|
+
status: job.status || null,
|
|
342
|
+
stage: job.stage || null,
|
|
343
|
+
progressCurrent: job.progressCurrent ?? job.progress_current ?? null,
|
|
344
|
+
progressTotal: job.progressTotal ?? job.progress_total ?? null,
|
|
345
|
+
attempts: job.attempts ?? null,
|
|
346
|
+
error: job.error || null,
|
|
347
|
+
createdAt: job.createdAt ?? job.created_at ?? null,
|
|
348
|
+
updatedAt: job.updatedAt ?? job.updated_at ?? null,
|
|
349
|
+
origin: job.origin || null,
|
|
350
|
+
sourcePath: job.sourcePath || job.source_path || null,
|
|
351
|
+
sourceUrl: job.sourceUrl || job.source_url || null,
|
|
352
|
+
batchId: job.batchId || job.batch_id || null,
|
|
353
|
+
clientItemId: job.clientItemId || job.client_item_id || null,
|
|
354
|
+
externalAssetId: job.externalAssetId || job.external_asset_id || null,
|
|
355
|
+
};
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
function documentArrayFromPayload(payload) {
|
|
359
|
+
if (Array.isArray(payload)) return payload;
|
|
360
|
+
if (payload && Array.isArray(payload.documents)) return payload.documents;
|
|
361
|
+
if (payload && Array.isArray(payload.items)) return payload.items;
|
|
362
|
+
return null;
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
function jobArrayFromPayload(payload) {
|
|
366
|
+
if (Array.isArray(payload)) return payload;
|
|
367
|
+
if (payload && Array.isArray(payload.jobs)) return payload.jobs;
|
|
368
|
+
if (payload && Array.isArray(payload.items)) return payload.items;
|
|
369
|
+
return null;
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
function mediaType(raw) {
|
|
373
|
+
return trimString(raw).toLowerCase().split(";")[0].trim();
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
function isTextLikeContentType(raw) {
|
|
377
|
+
const type = mediaType(raw);
|
|
378
|
+
if (!type) return false;
|
|
379
|
+
if (type.startsWith("text/")) return true;
|
|
380
|
+
return [
|
|
381
|
+
"application/ecmascript",
|
|
382
|
+
"application/javascript",
|
|
383
|
+
"application/json",
|
|
384
|
+
"application/sql",
|
|
385
|
+
"application/toml",
|
|
386
|
+
"application/x-ndjson",
|
|
387
|
+
"application/x-yaml",
|
|
388
|
+
"application/xhtml+xml",
|
|
389
|
+
"application/xml",
|
|
390
|
+
"application/yaml",
|
|
391
|
+
].includes(type) || type.endsWith("+json") || type.endsWith("+xml");
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
function contentLengthOf(headers) {
|
|
395
|
+
const raw = trimString(headers?.get?.("content-length"));
|
|
396
|
+
if (!raw) return null;
|
|
397
|
+
const n = Number(raw);
|
|
398
|
+
return Number.isFinite(n) && n >= 0 ? n : null;
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
async function readBoundedTextResponse(toolName, res, maxChars) {
|
|
402
|
+
const contentType = res.headers.get("content-type") || "";
|
|
403
|
+
const contentDisposition = res.headers.get("content-disposition") || null;
|
|
404
|
+
const contentLength = contentLengthOf(res.headers);
|
|
405
|
+
if (!isTextLikeContentType(contentType)) {
|
|
406
|
+
try { await res.body?.cancel?.(); } catch { /* ignore cleanup errors */ }
|
|
407
|
+
throw new Error(
|
|
408
|
+
toolName + ": raw document is not text-like" +
|
|
409
|
+
" (contentType=" + (contentType || "unknown") +
|
|
410
|
+
(contentLength != null ? ", contentLength=" + contentLength : "") +
|
|
411
|
+
(contentDisposition ? ", contentDisposition=" + contentDisposition : "") +
|
|
412
|
+
"). Use kb_get_document for metadata; binary originals should be opened through the file surface.",
|
|
413
|
+
);
|
|
414
|
+
}
|
|
415
|
+
if (!res.body || typeof res.body.getReader !== "function") {
|
|
416
|
+
throw new Error(toolName + ": upstream response does not support bounded streaming");
|
|
417
|
+
}
|
|
418
|
+
const reader = res.body.getReader();
|
|
419
|
+
const decoder = new TextDecoder("utf-8", { fatal: false });
|
|
420
|
+
let text = "";
|
|
421
|
+
let bytesRead = 0;
|
|
422
|
+
let truncated = false;
|
|
423
|
+
try {
|
|
424
|
+
while (text.length <= maxChars) {
|
|
425
|
+
const chunk = await reader.read();
|
|
426
|
+
if (chunk.done) break;
|
|
427
|
+
const value = chunk.value || new Uint8Array();
|
|
428
|
+
bytesRead += value.byteLength || 0;
|
|
429
|
+
text += decoder.decode(value, { stream: true });
|
|
430
|
+
if (text.length > maxChars) {
|
|
431
|
+
truncated = true;
|
|
432
|
+
try { await reader.cancel(); } catch { /* ignore cleanup errors */ }
|
|
433
|
+
break;
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
if (!truncated) {
|
|
437
|
+
text += decoder.decode();
|
|
438
|
+
if (text.length > maxChars) {
|
|
439
|
+
truncated = true;
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
} finally {
|
|
443
|
+
try { reader.releaseLock?.(); } catch { /* ignore cleanup errors */ }
|
|
444
|
+
}
|
|
445
|
+
if (truncated) {
|
|
446
|
+
text = text.slice(0, Math.max(0, maxChars - 1)) + "…";
|
|
447
|
+
}
|
|
448
|
+
return {
|
|
449
|
+
text,
|
|
450
|
+
truncated,
|
|
451
|
+
characters: text.length,
|
|
452
|
+
bytesRead,
|
|
453
|
+
contentLength,
|
|
454
|
+
};
|
|
455
|
+
}
|
|
456
|
+
|
|
250
457
|
function normalizeChunksResponse(payload) {
|
|
251
458
|
const j = payload && typeof payload === "object" ? payload : {};
|
|
252
459
|
const rawChunks = Array.isArray(j.chunks) ? j.chunks
|
|
@@ -384,6 +591,7 @@ async function kbList() {
|
|
|
384
591
|
name: item?.name || null,
|
|
385
592
|
description: item?.description ?? null,
|
|
386
593
|
chunks: item?.chunks ?? null,
|
|
594
|
+
documents: item?.documents ?? item?.docCount ?? item?.documentCount ?? null,
|
|
387
595
|
createdAt: item?.created_at ?? null,
|
|
388
596
|
usable: false,
|
|
389
597
|
unavailableReason: null,
|
|
@@ -399,6 +607,11 @@ async function kbList() {
|
|
|
399
607
|
{ headers: { Accept: "application/json" } },
|
|
400
608
|
);
|
|
401
609
|
if (res.ok) {
|
|
610
|
+
const docs = await res.json();
|
|
611
|
+
const docRows = documentArrayFromPayload(docs);
|
|
612
|
+
if (docRows) {
|
|
613
|
+
row.documents = docRows.length;
|
|
614
|
+
}
|
|
402
615
|
row.usable = true;
|
|
403
616
|
return row;
|
|
404
617
|
}
|
|
@@ -434,6 +647,41 @@ async function kbCreate(name, kbId, description) {
|
|
|
434
647
|
};
|
|
435
648
|
}
|
|
436
649
|
|
|
650
|
+
async function kbGetCapabilities() {
|
|
651
|
+
const payload = await readJson("kb_get_capabilities", "/api/service/capabilities");
|
|
652
|
+
return {
|
|
653
|
+
contractVersion: payload?.contractVersion || null,
|
|
654
|
+
serviceVersion: payload?.serviceVersion || null,
|
|
655
|
+
auth: payload?.auth || null,
|
|
656
|
+
features: payload?.features || {},
|
|
657
|
+
limits: payload?.limits || {},
|
|
658
|
+
upload: payload?.upload ? {
|
|
659
|
+
shortFormats: payload.upload.shortFormats || [],
|
|
660
|
+
formatsDetail: payload.upload.formatsDetail || null,
|
|
661
|
+
extensions: payload.upload.extensions || [],
|
|
662
|
+
} : null,
|
|
663
|
+
routes: payload?.routes || null,
|
|
664
|
+
};
|
|
665
|
+
}
|
|
666
|
+
|
|
667
|
+
async function kbGet(kbIdRaw) {
|
|
668
|
+
const kbId = defaultKbId(kbIdRaw, "kb_get");
|
|
669
|
+
const payload = await readJson(
|
|
670
|
+
"kb_get",
|
|
671
|
+
"/api/kb/" + encodePathPart(kbId),
|
|
672
|
+
);
|
|
673
|
+
return {
|
|
674
|
+
id: payload?.id || kbId,
|
|
675
|
+
name: payload?.name || null,
|
|
676
|
+
description: payload?.description ?? null,
|
|
677
|
+
documents: payload?.documents ?? payload?.docCount ?? payload?.documentCount ?? null,
|
|
678
|
+
chunks: payload?.chunks ?? null,
|
|
679
|
+
jobs: payload?.jobs ?? payload?.jobCount ?? null,
|
|
680
|
+
createdAt: payload?.created_at ?? payload?.createdAt ?? null,
|
|
681
|
+
config: payload?.config || payload?.retrieval || null,
|
|
682
|
+
};
|
|
683
|
+
}
|
|
684
|
+
|
|
437
685
|
async function kbSearch(query, kbIdRaw, topK) {
|
|
438
686
|
const trimmedQuery = trimString(query);
|
|
439
687
|
if (!trimmedQuery) throw new Error("kb_search: missing 'query' argument");
|
|
@@ -488,17 +736,205 @@ async function kbListDocuments(kbIdRaw) {
|
|
|
488
736
|
"kb_list_documents",
|
|
489
737
|
"/api/kb/" + encodeURIComponent(kbId) + "/documents",
|
|
490
738
|
);
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
739
|
+
const docs = documentArrayFromPayload(payload);
|
|
740
|
+
if (!docs) {
|
|
741
|
+
throw new Error("kb_list_documents: upstream returned a non-array document payload");
|
|
742
|
+
}
|
|
743
|
+
return docs.map((item) => normalizeDocument(item, kbId));
|
|
744
|
+
}
|
|
745
|
+
|
|
746
|
+
async function kbGetDocument(kbIdRaw, documentIdRaw) {
|
|
747
|
+
const kbId = defaultKbId(kbIdRaw, "kb_get_document");
|
|
748
|
+
const documentId = trimString(documentIdRaw);
|
|
749
|
+
if (!documentId) throw new Error("kb_get_document: missing 'documentId' argument");
|
|
750
|
+
const payload = await readJson(
|
|
751
|
+
"kb_get_document",
|
|
752
|
+
"/api/kb/" + encodePathPart(kbId) + "/documents/" + encodePathPart(documentId),
|
|
753
|
+
);
|
|
754
|
+
return normalizeDocument(payload, kbId);
|
|
755
|
+
}
|
|
756
|
+
|
|
757
|
+
async function kbListDocumentChunks(kbIdRaw, documentIdRaw) {
|
|
758
|
+
const kbId = defaultKbId(kbIdRaw, "kb_list_document_chunks");
|
|
759
|
+
const documentId = trimString(documentIdRaw);
|
|
760
|
+
if (!documentId) throw new Error("kb_list_document_chunks: missing 'documentId' argument");
|
|
761
|
+
const payload = await readJson(
|
|
762
|
+
"kb_list_document_chunks",
|
|
763
|
+
"/api/kb/" + encodePathPart(kbId) + "/documents/" + encodePathPart(documentId) + "/chunks",
|
|
764
|
+
);
|
|
765
|
+
const rawChunks = Array.isArray(payload) ? payload : Array.isArray(payload?.chunks) ? payload.chunks : null;
|
|
766
|
+
if (!rawChunks) {
|
|
767
|
+
throw new Error("kb_list_document_chunks: upstream returned a non-array chunks payload");
|
|
768
|
+
}
|
|
769
|
+
return rawChunks.map((item, idx) => {
|
|
770
|
+
const chunk = item && typeof item === "object" ? item : { text: String(item ?? "") };
|
|
771
|
+
const capped = cappedText(chunk.text || chunk.content || "", 1600);
|
|
772
|
+
return {
|
|
773
|
+
id: chunk.id ?? null,
|
|
774
|
+
chunkIndex: chunk.chunk_index ?? chunk.chunkIndex ?? idx,
|
|
775
|
+
page: chunk.page ?? null,
|
|
776
|
+
text: capped.text,
|
|
777
|
+
truncated: capped.truncated,
|
|
778
|
+
characters: capped.characters,
|
|
779
|
+
};
|
|
780
|
+
});
|
|
781
|
+
}
|
|
782
|
+
|
|
783
|
+
async function kbReadDocumentRaw(kbIdRaw, documentIdRaw) {
|
|
784
|
+
const kbId = defaultKbId(kbIdRaw, "kb_read_document_raw");
|
|
785
|
+
const documentId = trimString(documentIdRaw);
|
|
786
|
+
if (!documentId) throw new Error("kb_read_document_raw: missing 'documentId' argument");
|
|
787
|
+
const res = await fetchWithTimeout(
|
|
788
|
+
"kb_read_document_raw",
|
|
789
|
+
"/api/kb/" + encodePathPart(kbId) + "/documents/" + encodePathPart(documentId) + "/raw",
|
|
790
|
+
{ headers: { Accept: "text/plain, application/octet-stream;q=0.5, */*;q=0.1" } },
|
|
791
|
+
);
|
|
792
|
+
if (!res.ok) {
|
|
793
|
+
const txt = await res.text();
|
|
794
|
+
throw new Error("kb_read_document_raw: upstream " + res.status + ": " + txt.slice(0, 400));
|
|
795
|
+
}
|
|
796
|
+
const capped = await readBoundedTextResponse("kb_read_document_raw", res, MAX_TEXT_RESPONSE_CHARS);
|
|
797
|
+
return {
|
|
798
|
+
kbId,
|
|
799
|
+
documentId,
|
|
800
|
+
contentType: res.headers.get("content-type") || null,
|
|
801
|
+
contentDisposition: res.headers.get("content-disposition") || null,
|
|
802
|
+
text: capped.text,
|
|
803
|
+
truncated: capped.truncated,
|
|
804
|
+
characters: capped.characters,
|
|
805
|
+
bytesRead: capped.bytesRead,
|
|
806
|
+
contentLength: capped.contentLength,
|
|
807
|
+
};
|
|
808
|
+
}
|
|
809
|
+
|
|
810
|
+
async function kbListDocumentFaq(kbIdRaw, documentIdRaw) {
|
|
811
|
+
const kbId = defaultKbId(kbIdRaw, "kb_list_document_faq");
|
|
812
|
+
const documentId = trimString(documentIdRaw);
|
|
813
|
+
if (!documentId) throw new Error("kb_list_document_faq: missing 'documentId' argument");
|
|
814
|
+
const payload = await readJson(
|
|
815
|
+
"kb_list_document_faq",
|
|
816
|
+
"/api/kb/" + encodePathPart(kbId) + "/documents/" + encodePathPart(documentId) + "/faq",
|
|
817
|
+
);
|
|
818
|
+
const faqs = Array.isArray(payload) ? payload : Array.isArray(payload?.faqs) ? payload.faqs : null;
|
|
819
|
+
if (!faqs) {
|
|
820
|
+
throw new Error("kb_list_document_faq: upstream returned a non-array FAQ payload");
|
|
821
|
+
}
|
|
822
|
+
return faqs;
|
|
823
|
+
}
|
|
824
|
+
|
|
825
|
+
async function kbReindexDocument(kbIdRaw, documentIdRaw, confirmDocumentIdRaw) {
|
|
826
|
+
const kbId = requireKbId(kbIdRaw, "kb_reindex_document");
|
|
827
|
+
const documentId = trimString(documentIdRaw);
|
|
828
|
+
if (!documentId) throw new Error("kb_reindex_document: missing 'documentId' argument");
|
|
829
|
+
requireConfirm(confirmDocumentIdRaw, documentId, "kb_reindex_document", "confirmDocumentId");
|
|
830
|
+
const payload = await readJson(
|
|
831
|
+
"kb_reindex_document",
|
|
832
|
+
"/api/kb/" + encodePathPart(kbId) + "/documents/" + encodePathPart(documentId) + "/reindex",
|
|
833
|
+
{ method: "POST", headers: { "Content-Type": "application/json" }, body: "{}" },
|
|
834
|
+
);
|
|
835
|
+
return {
|
|
836
|
+
kbId,
|
|
837
|
+
documentId,
|
|
838
|
+
doc: payload?.doc ? normalizeDocument(payload.doc, kbId) : null,
|
|
839
|
+
parents: payload?.parents ?? null,
|
|
840
|
+
chunks: payload?.chunks ?? null,
|
|
841
|
+
removedChunks: payload?.removedChunks ?? null,
|
|
842
|
+
faqRegeneration: payload?.faqRegeneration || null,
|
|
843
|
+
sourceGeneration: payload?.sourceGeneration || null,
|
|
844
|
+
};
|
|
845
|
+
}
|
|
846
|
+
|
|
847
|
+
async function kbImportUrl(args) {
|
|
848
|
+
const kbId = requireKbId(args?.kbId, "kb_import_url");
|
|
849
|
+
const url = trimString(args?.url);
|
|
850
|
+
if (!url) throw new Error("kb_import_url: missing 'url' argument");
|
|
851
|
+
const asyncMode = boolWithDefault(args?.async, true);
|
|
852
|
+
const payload = { url };
|
|
853
|
+
for (const key of ["origin", "sourcePath", "batchId", "clientItemId", "externalAssetId"]) {
|
|
854
|
+
const value = optionalString(args?.[key]);
|
|
855
|
+
if (value) payload[key] = value;
|
|
856
|
+
}
|
|
857
|
+
const headers = { "Content-Type": "application/json" };
|
|
858
|
+
const idempotencyKey = optionalString(args?.idempotencyKey);
|
|
859
|
+
if (idempotencyKey) headers["Idempotency-Key"] = idempotencyKey;
|
|
860
|
+
const result = await readJson(
|
|
861
|
+
"kb_import_url",
|
|
862
|
+
"/api/kb/" + encodePathPart(kbId) + "/import" + (asyncMode ? "?async=true" : ""),
|
|
863
|
+
{ method: "POST", headers, body: JSON.stringify(payload) },
|
|
864
|
+
);
|
|
865
|
+
return {
|
|
866
|
+
kbId,
|
|
867
|
+
async: asyncMode,
|
|
868
|
+
sourceUrl: result?.sourceUrl || null,
|
|
869
|
+
job: result?.job ? normalizeJob(result.job, kbId) : null,
|
|
870
|
+
doc: result?.doc ? normalizeDocument(result.doc, kbId) : null,
|
|
871
|
+
chunks: result?.chunks ?? null,
|
|
872
|
+
parents: result?.parents ?? null,
|
|
873
|
+
idempotencyKey: result?.idempotencyKey || idempotencyKey || null,
|
|
874
|
+
replayed: !!result?.replayed,
|
|
875
|
+
};
|
|
876
|
+
}
|
|
877
|
+
|
|
878
|
+
async function kbListJobs(args) {
|
|
879
|
+
const kbId = defaultKbId(args?.kbId, "kb_list_jobs");
|
|
880
|
+
const qs = new URLSearchParams();
|
|
881
|
+
const limit = positiveInt(args?.limit, null, 100);
|
|
882
|
+
if (limit) qs.set("limit", String(limit));
|
|
883
|
+
appendOptionalQuery(qs, "cursor", args?.cursor);
|
|
884
|
+
appendOptionalQuery(qs, "status", args?.status);
|
|
885
|
+
appendOptionalQuery(qs, "clientItemId", args?.clientItemId);
|
|
886
|
+
appendOptionalQuery(qs, "batchId", args?.batchId);
|
|
887
|
+
const query = qs.toString();
|
|
888
|
+
const payload = await readJson(
|
|
889
|
+
"kb_list_jobs",
|
|
890
|
+
"/api/kb/" + encodePathPart(kbId) + "/jobs" + (query ? "?" + query : ""),
|
|
891
|
+
);
|
|
892
|
+
const jobs = jobArrayFromPayload(payload);
|
|
893
|
+
if (!jobs) {
|
|
894
|
+
throw new Error("kb_list_jobs: upstream returned a non-array jobs payload");
|
|
895
|
+
}
|
|
896
|
+
return {
|
|
897
|
+
jobs: jobs.map((item) => normalizeJob(item, kbId)),
|
|
898
|
+
nextCursor: payload?.nextCursor ?? null,
|
|
899
|
+
totalEstimate: payload?.totalEstimate ?? null,
|
|
900
|
+
limit: payload?.limit ?? limit ?? null,
|
|
901
|
+
};
|
|
902
|
+
}
|
|
903
|
+
|
|
904
|
+
async function kbGetJob(kbIdRaw, jobIdRaw) {
|
|
905
|
+
const kbId = defaultKbId(kbIdRaw, "kb_get_job");
|
|
906
|
+
const jobId = trimString(jobIdRaw);
|
|
907
|
+
if (!jobId) throw new Error("kb_get_job: missing 'jobId' argument");
|
|
908
|
+
const payload = await readJson(
|
|
909
|
+
"kb_get_job",
|
|
910
|
+
"/api/kb/" + encodePathPart(kbId) + "/jobs/" + encodePathPart(jobId),
|
|
911
|
+
);
|
|
912
|
+
return normalizeJob(payload, kbId);
|
|
913
|
+
}
|
|
914
|
+
|
|
915
|
+
async function kbRetryJob(kbIdRaw, jobIdRaw) {
|
|
916
|
+
const kbId = requireKbId(kbIdRaw, "kb_retry_job");
|
|
917
|
+
const jobId = trimString(jobIdRaw);
|
|
918
|
+
if (!jobId) throw new Error("kb_retry_job: missing 'jobId' argument");
|
|
919
|
+
const payload = await readJson(
|
|
920
|
+
"kb_retry_job",
|
|
921
|
+
"/api/kb/" + encodePathPart(kbId) + "/jobs/" + encodePathPart(jobId) + "/retry",
|
|
922
|
+
{ method: "POST", headers: { "Content-Type": "application/json" }, body: "{}" },
|
|
923
|
+
);
|
|
924
|
+
return normalizeJob(payload, kbId);
|
|
925
|
+
}
|
|
926
|
+
|
|
927
|
+
async function kbCancelJob(kbIdRaw, jobIdRaw, confirmJobIdRaw) {
|
|
928
|
+
const kbId = requireKbId(kbIdRaw, "kb_cancel_job");
|
|
929
|
+
const jobId = trimString(jobIdRaw);
|
|
930
|
+
if (!jobId) throw new Error("kb_cancel_job: missing 'jobId' argument");
|
|
931
|
+
requireConfirm(confirmJobIdRaw, jobId, "kb_cancel_job", "confirmJobId");
|
|
932
|
+
const payload = await readJson(
|
|
933
|
+
"kb_cancel_job",
|
|
934
|
+
"/api/kb/" + encodePathPart(kbId) + "/jobs/" + encodePathPart(jobId) + "/cancel",
|
|
935
|
+
{ method: "POST", headers: { "Content-Type": "application/json" }, body: "{}" },
|
|
936
|
+
);
|
|
937
|
+
return normalizeJob(payload, kbId);
|
|
502
938
|
}
|
|
503
939
|
|
|
504
940
|
async function kbReadHandbook(section) {
|
|
@@ -554,7 +990,12 @@ async function kbDeleteKb(kbIdRaw, confirmKbIdRaw) {
|
|
|
554
990
|
const TOOLS = [
|
|
555
991
|
{
|
|
556
992
|
name: "kb_list",
|
|
557
|
-
description: "List knowledge bases and validate whether each id can be used by document/search APIs. Only use entries with usable=true for follow-up calls.",
|
|
993
|
+
description: "List knowledge bases and validate whether each id can be used by document/search APIs. Returns documents=file count and chunks=index chunk count; use documents when the user asks how many files are in a KB. Only use entries with usable=true for follow-up calls.",
|
|
994
|
+
inputSchema: { type: "object", properties: {} },
|
|
995
|
+
},
|
|
996
|
+
{
|
|
997
|
+
name: "kb_get_capabilities",
|
|
998
|
+
description: "Read the JishuShell-KB external-control capability summary, including enabled features, upload formats, limits, and route inventory pointer. Does not expose secrets.",
|
|
558
999
|
inputSchema: { type: "object", properties: {} },
|
|
559
1000
|
},
|
|
560
1001
|
{
|
|
@@ -570,6 +1011,16 @@ const TOOLS = [
|
|
|
570
1011
|
required: ["name"],
|
|
571
1012
|
},
|
|
572
1013
|
},
|
|
1014
|
+
{
|
|
1015
|
+
name: "kb_get",
|
|
1016
|
+
description: "Read one knowledge base's metadata, counts, and safe retrieval/config summary. If kbId is omitted the wired default KB is used.",
|
|
1017
|
+
inputSchema: {
|
|
1018
|
+
type: "object",
|
|
1019
|
+
properties: {
|
|
1020
|
+
kbId: { type: "string", description: "Optional KB id; defaults to the wired default KB" },
|
|
1021
|
+
},
|
|
1022
|
+
},
|
|
1023
|
+
},
|
|
573
1024
|
{
|
|
574
1025
|
name: "kb_search",
|
|
575
1026
|
description: "Search a knowledge base for chunks relevant to a question. Use whenever the user asks something likely answered by indexed documents. If kbId is omitted the default KB is used.",
|
|
@@ -605,6 +1056,138 @@ const TOOLS = [
|
|
|
605
1056
|
},
|
|
606
1057
|
},
|
|
607
1058
|
},
|
|
1059
|
+
{
|
|
1060
|
+
name: "kb_get_document",
|
|
1061
|
+
description: "Read one indexed document's metadata and derived counts. Use after kb_list_documents when the user asks about a specific document.",
|
|
1062
|
+
inputSchema: {
|
|
1063
|
+
type: "object",
|
|
1064
|
+
properties: {
|
|
1065
|
+
kbId: { type: "string", description: "Optional KB id; defaults to the wired default KB" },
|
|
1066
|
+
documentId: { type: "string", description: "Document id to inspect" },
|
|
1067
|
+
},
|
|
1068
|
+
required: ["documentId"],
|
|
1069
|
+
},
|
|
1070
|
+
},
|
|
1071
|
+
{
|
|
1072
|
+
name: "kb_list_document_chunks",
|
|
1073
|
+
description: "List indexed chunks for a document. Use to inspect why search matched a document or to debug chunking. Chunk text is capped in the MCP response.",
|
|
1074
|
+
inputSchema: {
|
|
1075
|
+
type: "object",
|
|
1076
|
+
properties: {
|
|
1077
|
+
kbId: { type: "string", description: "Optional KB id; defaults to the wired default KB" },
|
|
1078
|
+
documentId: { type: "string", description: "Document id to inspect" },
|
|
1079
|
+
},
|
|
1080
|
+
required: ["documentId"],
|
|
1081
|
+
},
|
|
1082
|
+
},
|
|
1083
|
+
{
|
|
1084
|
+
name: "kb_read_document_raw",
|
|
1085
|
+
description: "Read the original stored document text for a document id. Use only when the user asks to inspect the source document or search snippets are insufficient. Output is capped.",
|
|
1086
|
+
inputSchema: {
|
|
1087
|
+
type: "object",
|
|
1088
|
+
properties: {
|
|
1089
|
+
kbId: { type: "string", description: "Optional KB id; defaults to the wired default KB" },
|
|
1090
|
+
documentId: { type: "string", description: "Document id to read" },
|
|
1091
|
+
},
|
|
1092
|
+
required: ["documentId"],
|
|
1093
|
+
},
|
|
1094
|
+
},
|
|
1095
|
+
{
|
|
1096
|
+
name: "kb_list_document_faq",
|
|
1097
|
+
description: "List generated FAQ suggestions for a document, if the KB has generated any.",
|
|
1098
|
+
inputSchema: {
|
|
1099
|
+
type: "object",
|
|
1100
|
+
properties: {
|
|
1101
|
+
kbId: { type: "string", description: "Optional KB id; defaults to the wired default KB" },
|
|
1102
|
+
documentId: { type: "string", description: "Document id to inspect" },
|
|
1103
|
+
},
|
|
1104
|
+
required: ["documentId"],
|
|
1105
|
+
},
|
|
1106
|
+
},
|
|
1107
|
+
{
|
|
1108
|
+
name: "kb_reindex_document",
|
|
1109
|
+
description: "Rebuild one document's chunks, vectors, and FAQ suggestions from the stored raw file. This is a write/repair action; only use after explicit user confirmation.",
|
|
1110
|
+
inputSchema: {
|
|
1111
|
+
type: "object",
|
|
1112
|
+
properties: {
|
|
1113
|
+
kbId: { type: "string", description: "Target KB id" },
|
|
1114
|
+
documentId: { type: "string", description: "Document id to reindex" },
|
|
1115
|
+
confirmDocumentId: { type: "string", description: "Must exactly equal documentId" },
|
|
1116
|
+
},
|
|
1117
|
+
required: ["kbId", "documentId", "confirmDocumentId"],
|
|
1118
|
+
},
|
|
1119
|
+
},
|
|
1120
|
+
{
|
|
1121
|
+
name: "kb_import_url",
|
|
1122
|
+
description: "Fetch a readable remote URL and index its extracted text into a specific KB. Defaults to async=true and returns an ingest job; use kb_get_job to check progress.",
|
|
1123
|
+
inputSchema: {
|
|
1124
|
+
type: "object",
|
|
1125
|
+
properties: {
|
|
1126
|
+
kbId: { type: "string", description: "Target KB id (required for writes)" },
|
|
1127
|
+
url: { type: "string", description: "User-provided URL to import" },
|
|
1128
|
+
async: { type: "boolean", description: "Whether to enqueue async ingest; defaults to true" },
|
|
1129
|
+
idempotencyKey: { type: "string", description: "Optional idempotency key for safe retries" },
|
|
1130
|
+
origin: { type: "string", description: "Optional provenance origin" },
|
|
1131
|
+
sourcePath: { type: "string", description: "Optional caller-visible source path" },
|
|
1132
|
+
batchId: { type: "string", description: "Optional batch id" },
|
|
1133
|
+
clientItemId: { type: "string", description: "Optional caller item id" },
|
|
1134
|
+
externalAssetId: { type: "string", description: "Optional external asset id" },
|
|
1135
|
+
},
|
|
1136
|
+
required: ["kbId", "url"],
|
|
1137
|
+
},
|
|
1138
|
+
},
|
|
1139
|
+
{
|
|
1140
|
+
name: "kb_list_jobs",
|
|
1141
|
+
description: "List recent ingest jobs for a KB, with optional status/clientItemId/batchId filters and pagination.",
|
|
1142
|
+
inputSchema: {
|
|
1143
|
+
type: "object",
|
|
1144
|
+
properties: {
|
|
1145
|
+
kbId: { type: "string", description: "Optional KB id; defaults to the wired default KB" },
|
|
1146
|
+
limit: { type: "number", description: "Optional page size, max 100" },
|
|
1147
|
+
cursor: { type: "string", description: "Optional pagination cursor" },
|
|
1148
|
+
status: { type: "string", description: "Optional job status filter" },
|
|
1149
|
+
clientItemId: { type: "string", description: "Optional client item id filter" },
|
|
1150
|
+
batchId: { type: "string", description: "Optional batch id filter" },
|
|
1151
|
+
},
|
|
1152
|
+
},
|
|
1153
|
+
},
|
|
1154
|
+
{
|
|
1155
|
+
name: "kb_get_job",
|
|
1156
|
+
description: "Read one ingest job's current status and provenance.",
|
|
1157
|
+
inputSchema: {
|
|
1158
|
+
type: "object",
|
|
1159
|
+
properties: {
|
|
1160
|
+
kbId: { type: "string", description: "Optional KB id; defaults to the wired default KB" },
|
|
1161
|
+
jobId: { type: "string", description: "Ingest job id" },
|
|
1162
|
+
},
|
|
1163
|
+
required: ["jobId"],
|
|
1164
|
+
},
|
|
1165
|
+
},
|
|
1166
|
+
{
|
|
1167
|
+
name: "kb_retry_job",
|
|
1168
|
+
description: "Retry one failed or cancelled ingest job. This is a write/repair action; use only when the user asks to retry.",
|
|
1169
|
+
inputSchema: {
|
|
1170
|
+
type: "object",
|
|
1171
|
+
properties: {
|
|
1172
|
+
kbId: { type: "string", description: "Target KB id" },
|
|
1173
|
+
jobId: { type: "string", description: "Ingest job id to retry" },
|
|
1174
|
+
},
|
|
1175
|
+
required: ["kbId", "jobId"],
|
|
1176
|
+
},
|
|
1177
|
+
},
|
|
1178
|
+
{
|
|
1179
|
+
name: "kb_cancel_job",
|
|
1180
|
+
description: "Cancel one queued or running ingest job. Only use after explicit user confirmation. The confirmation field must exactly equal the target job id.",
|
|
1181
|
+
inputSchema: {
|
|
1182
|
+
type: "object",
|
|
1183
|
+
properties: {
|
|
1184
|
+
kbId: { type: "string", description: "Target KB id" },
|
|
1185
|
+
jobId: { type: "string", description: "Ingest job id to cancel" },
|
|
1186
|
+
confirmJobId: { type: "string", description: "Must exactly equal jobId" },
|
|
1187
|
+
},
|
|
1188
|
+
required: ["kbId", "jobId", "confirmJobId"],
|
|
1189
|
+
},
|
|
1190
|
+
},
|
|
608
1191
|
{
|
|
609
1192
|
name: "kb_read_handbook",
|
|
610
1193
|
description: "Read the JishuShell-KB handbook. Use this to answer how the KB settings work or what a handbook section says. Section matching uses exact heading text after whitespace normalization.",
|
|
@@ -674,8 +1257,12 @@ async function handle(req) {
|
|
|
674
1257
|
const a = params?.arguments || {};
|
|
675
1258
|
if (tool === "kb_list") {
|
|
676
1259
|
reply(id, { content: [{ type: "text", text: jsonText(await kbList()) }] });
|
|
1260
|
+
} else if (tool === "kb_get_capabilities") {
|
|
1261
|
+
reply(id, { content: [{ type: "text", text: jsonText(await kbGetCapabilities()) }] });
|
|
677
1262
|
} else if (tool === "kb_create") {
|
|
678
1263
|
reply(id, { content: [{ type: "text", text: jsonText(await kbCreate(a.name, a.id, a.description)) }] });
|
|
1264
|
+
} else if (tool === "kb_get") {
|
|
1265
|
+
reply(id, { content: [{ type: "text", text: jsonText(await kbGet(a.kbId)) }] });
|
|
679
1266
|
} else if (tool === "kb_search") {
|
|
680
1267
|
reply(id, { content: [{ type: "text", text: fmtSearchResult(await kbSearch(a.query, a.kbId, a.topK)) }] });
|
|
681
1268
|
} else if (tool === "kb_upload") {
|
|
@@ -691,6 +1278,26 @@ async function handle(req) {
|
|
|
691
1278
|
});
|
|
692
1279
|
} else if (tool === "kb_list_documents") {
|
|
693
1280
|
reply(id, { content: [{ type: "text", text: jsonText(await kbListDocuments(a.kbId)) }] });
|
|
1281
|
+
} else if (tool === "kb_get_document") {
|
|
1282
|
+
reply(id, { content: [{ type: "text", text: jsonText(await kbGetDocument(a.kbId, a.documentId)) }] });
|
|
1283
|
+
} else if (tool === "kb_list_document_chunks") {
|
|
1284
|
+
reply(id, { content: [{ type: "text", text: jsonText(await kbListDocumentChunks(a.kbId, a.documentId)) }] });
|
|
1285
|
+
} else if (tool === "kb_read_document_raw") {
|
|
1286
|
+
reply(id, { content: [{ type: "text", text: jsonText(await kbReadDocumentRaw(a.kbId, a.documentId)) }] });
|
|
1287
|
+
} else if (tool === "kb_list_document_faq") {
|
|
1288
|
+
reply(id, { content: [{ type: "text", text: jsonText(await kbListDocumentFaq(a.kbId, a.documentId)) }] });
|
|
1289
|
+
} else if (tool === "kb_reindex_document") {
|
|
1290
|
+
reply(id, { content: [{ type: "text", text: jsonText(await kbReindexDocument(a.kbId, a.documentId, a.confirmDocumentId)) }] });
|
|
1291
|
+
} else if (tool === "kb_import_url") {
|
|
1292
|
+
reply(id, { content: [{ type: "text", text: jsonText(await kbImportUrl(a)) }] });
|
|
1293
|
+
} else if (tool === "kb_list_jobs") {
|
|
1294
|
+
reply(id, { content: [{ type: "text", text: jsonText(await kbListJobs(a)) }] });
|
|
1295
|
+
} else if (tool === "kb_get_job") {
|
|
1296
|
+
reply(id, { content: [{ type: "text", text: jsonText(await kbGetJob(a.kbId, a.jobId)) }] });
|
|
1297
|
+
} else if (tool === "kb_retry_job") {
|
|
1298
|
+
reply(id, { content: [{ type: "text", text: jsonText(await kbRetryJob(a.kbId, a.jobId)) }] });
|
|
1299
|
+
} else if (tool === "kb_cancel_job") {
|
|
1300
|
+
reply(id, { content: [{ type: "text", text: jsonText(await kbCancelJob(a.kbId, a.jobId, a.confirmJobId)) }] });
|
|
694
1301
|
} else if (tool === "kb_read_handbook") {
|
|
695
1302
|
reply(id, { content: [{ type: "text", text: await kbReadHandbook(a.section) }] });
|
|
696
1303
|
} else if (tool === "kb_get_config") {
|