agentworkshop 0.5.5 → 0.5.6

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.
Files changed (46) hide show
  1. package/.AgentWorkShop/prompts/compaction-hints.md +9 -0
  2. package/.AgentWorkShop/prompts/host-tools.json +664 -630
  3. package/.AgentWorkShop/prompts/peer-reply-cross-channel.md +10 -0
  4. package/.AgentWorkShop/prompts/system-manual.md +6 -1
  5. package/.output/.AgentWorkShop/prompts/compaction-hints.md +9 -0
  6. package/.output/.AgentWorkShop/prompts/host-tools.json +664 -630
  7. package/.output/.AgentWorkShop/prompts/peer-reply-cross-channel.md +10 -0
  8. package/.output/.AgentWorkShop/prompts/system-manual.md +6 -1
  9. package/.output/nitro.json +1 -1
  10. package/.output/public/_nuxt/builds/latest.json +1 -1
  11. package/.output/public/_nuxt/builds/meta/d50c6ec2-801c-4ba2-97d8-a4db401b702c.json +1 -0
  12. package/.output/server/chunks/_/nitro.mjs +1920 -1211
  13. package/.output/server/chunks/_/nitro.mjs.map +1 -1
  14. package/.output/server/chunks/routes/api/workshop/channels/_id/index3.post.mjs +25 -3
  15. package/.output/server/chunks/routes/api/workshop/channels/_id/index3.post.mjs.map +1 -1
  16. package/.output/server/package.json +1 -1
  17. package/package.json +1 -1
  18. package/scripts/_dbg-cross-channel-e2e.mjs +157 -0
  19. package/scripts/test-context-governor.ts +176 -0
  20. package/scripts/test-memory-brief-chronicle.ts +180 -0
  21. package/scripts/test-memory-dynamic.ts +3 -1
  22. package/scripts/test-memory-rrf-mmr.ts +114 -0
  23. package/server/api/workshop/channels/[id]/messages/index.post.ts +26 -1
  24. package/server/api/workshop/ws.ts +1 -0
  25. package/server/data/daqs.json +35 -13
  26. package/server/data/dcw-lines.json +14 -0
  27. package/server/data/dcw-products.json +14 -0
  28. package/server/data/dcw-recipes.json +28 -0
  29. package/server/data/dcw-rollback.json +122 -1
  30. package/server/data/dcw-runs.json +54 -36
  31. package/server/data/dcw-writes.json +60 -0
  32. package/server/data/dcws.json +42 -0
  33. package/server/data/line-runs.json +32 -22
  34. package/server/services/workshop/agents/adapters/omp-rpc-client.ts +65 -0
  35. package/server/services/workshop/agents/agent-interface.ts +26 -1
  36. package/server/services/workshop/agents/mock-agent.ts +12 -0
  37. package/server/services/workshop/agents/omp-agent.ts +277 -8
  38. package/server/services/workshop/db/database.ts +16 -1
  39. package/server/services/workshop/db/memory.repo.ts +22 -2
  40. package/server/services/workshop/prompts/loader.ts +6 -5
  41. package/server/services/workshop/runtime/agent-runtime.ts +52 -6
  42. package/server/services/workshop/runtime/channel-runtime.ts +14 -6
  43. package/server/services/workshop/runtime/manager.ts +192 -3
  44. package/server/services/workshop/runtime/memory.ts +313 -78
  45. package/server/services/workshop/types/task.ts +14 -0
  46. package/.output/public/_nuxt/builds/meta/f2f649c5-fd3b-4507-a3a1-8b4a194de72d.json +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"nitro.mjs","sources":["../../../../node_modules/.pnpm/uncrypto@0.1.3/node_modules/uncrypto/dist/crypto.node.mjs","../../../../node_modules/.pnpm/destr@2.0.5/node_modules/destr/dist/index.mjs","../../../../node_modules/.pnpm/ufo@1.6.4/node_modules/ufo/dist/index.mjs","../../../../node_modules/.pnpm/cookie-es@1.2.3/node_modules/cookie-es/dist/index.mjs","../../../../node_modules/.pnpm/radix3@1.1.2/node_modules/radix3/dist/index.mjs","../../../../node_modules/.pnpm/defu@6.1.7/node_modules/defu/dist/defu.mjs","../../../../node_modules/.pnpm/iron-webcrypto@1.2.1/node_modules/iron-webcrypto/dist/index.js","../../../../node_modules/.pnpm/node-mock-http@1.0.5/node_modules/node-mock-http/dist/index.mjs","../../../../node_modules/.pnpm/h3@1.15.11/node_modules/h3/dist/index.mjs","../../../../node_modules/.pnpm/hookable@5.5.3/node_modules/hookable/dist/index.mjs","../../../../node_modules/.pnpm/node-fetch-native@1.6.7/node_modules/node-fetch-native/dist/native.mjs","../../../../node_modules/.pnpm/ofetch@1.5.1/node_modules/ofetch/dist/shared/ofetch.CWycOUEr.mjs","../../../../node_modules/.pnpm/ofetch@1.5.1/node_modules/ofetch/dist/node.mjs","../../../../node_modules/.pnpm/unstorage@1.17.5_db0@0.3.4_ioredis@5.11.1/node_modules/unstorage/dist/shared/unstorage.zVDD2mZo.mjs","../../../../node_modules/.pnpm/unstorage@1.17.5_db0@0.3.4_ioredis@5.11.1/node_modules/unstorage/dist/index.mjs","../../../../node_modules/.pnpm/unstorage@1.17.5_db0@0.3.4_ioredis@5.11.1/node_modules/unstorage/drivers/utils/index.mjs","../../../../node_modules/.pnpm/unstorage@1.17.5_db0@0.3.4_ioredis@5.11.1/node_modules/unstorage/drivers/utils/node-fs.mjs","../../../../node_modules/.pnpm/unstorage@1.17.5_db0@0.3.4_ioredis@5.11.1/node_modules/unstorage/drivers/fs-lite.mjs","../../../../node_modules/.pnpm/nitropack@2.13.4_oxc-parser_b1d7d58181e96cbc69b3295f5f958520/node_modules/nitropack/dist/runtime/internal/storage.mjs","../../../../node_modules/.pnpm/ohash@2.0.11/node_modules/ohash/dist/shared/ohash.D__AXeF1.mjs","../../../../node_modules/.pnpm/ohash@2.0.11/node_modules/ohash/dist/crypto/node/index.mjs","../../../../node_modules/.pnpm/nitropack@2.13.4_oxc-parser_b1d7d58181e96cbc69b3295f5f958520/node_modules/nitropack/dist/runtime/internal/hash.mjs","../../../../node_modules/.pnpm/nitropack@2.13.4_oxc-parser_b1d7d58181e96cbc69b3295f5f958520/node_modules/nitropack/dist/runtime/internal/cache.mjs","../../../../node_modules/.pnpm/klona@2.0.6/node_modules/klona/dist/index.mjs","../../../../node_modules/.pnpm/scule@1.3.0/node_modules/scule/dist/index.mjs","../../../../node_modules/.pnpm/nitropack@2.13.4_oxc-parser_b1d7d58181e96cbc69b3295f5f958520/node_modules/nitropack/dist/runtime/internal/utils.env.mjs","../../../../node_modules/.pnpm/nitropack@2.13.4_oxc-parser_b1d7d58181e96cbc69b3295f5f958520/node_modules/nitropack/dist/runtime/internal/config.mjs","../../../../node_modules/.pnpm/nitropack@2.13.4_oxc-parser_b1d7d58181e96cbc69b3295f5f958520/node_modules/nitropack/dist/runtime/internal/route-rules-utils.mjs","../../../../node_modules/.pnpm/nitropack@2.13.4_oxc-parser_b1d7d58181e96cbc69b3295f5f958520/node_modules/nitropack/dist/runtime/internal/route-rules.mjs","../../../../node_modules/.pnpm/nitropack@2.13.4_oxc-parser_b1d7d58181e96cbc69b3295f5f958520/node_modules/nitropack/dist/runtime/internal/utils.mjs","../../../../node_modules/.pnpm/@nuxt+nitro-server@4.5.2_2b2a73a5ea3a6c1cac65dd2aa61911d0/node_modules/@nuxt/nitro-server/dist/runtime/utils/error.mjs","../../../../node_modules/.pnpm/@nuxt+nitro-server@4.5.2_2b2a73a5ea3a6c1cac65dd2aa61911d0/node_modules/@nuxt/nitro-server/dist/runtime/handlers/error.mjs","../../../../node_modules/.pnpm/nitropack@2.13.4_oxc-parser_b1d7d58181e96cbc69b3295f5f958520/node_modules/nitropack/dist/runtime/internal/error/utils.mjs","../../../../node_modules/.pnpm/nitropack@2.13.4_oxc-parser_b1d7d58181e96cbc69b3295f5f958520/node_modules/nitropack/dist/runtime/internal/error/prod.mjs","../../../../node_modules/.pnpm/nuxt-auth-utils@0.5.30_magi_25cfea03c37d60c613297752f2919dae/node_modules/nuxt-auth-utils/dist/runtime/server/plugins/oauth.js","../../../../node_modules/.pnpm/hookable@6.1.1/node_modules/hookable/dist/index.mjs","../../../../node_modules/.pnpm/nitropack@2.13.4_oxc-parser_b1d7d58181e96cbc69b3295f5f958520/node_modules/nitropack/dist/runtime/internal/plugin.mjs","../../../../node_modules/.pnpm/nitropack@2.13.4_oxc-parser_b1d7d58181e96cbc69b3295f5f958520/node_modules/nitropack/dist/runtime/internal/renderer.mjs","../../../../node_modules/.pnpm/@nuxt+nitro-server@4.5.2_2b2a73a5ea3a6c1cac65dd2aa61911d0/node_modules/@nuxt/nitro-server/dist/runtime/utils/paths.mjs","../../../../server/utils/errors.ts","../../../../sdk/hooks.mjs","../../../../sdk/api.mjs","../../../../sdk/context.mjs","../../../../server/services/workshop/plugins/host.mjs","../../../../server/services/workshop/scene-events.ts","../../../../server/services/workshop/ops/ops.ts","../../../../server/utils/approval-gate.ts","../../../../server/utils/auth.ts","../../../../server/utils/config.ts","../../../../server/utils/response.ts","../../../../server/utils/validate.ts","../../../../node_modules/.pnpm/nuxt-auth-utils@0.5.30_magi_25cfea03c37d60c613297752f2919dae/node_modules/nuxt-auth-utils/dist/runtime/server/utils/session.js","../../../../node_modules/.pnpm/nuxt-auth-utils@0.5.30_magi_25cfea03c37d60c613297752f2919dae/node_modules/nuxt-auth-utils/dist/runtime/server/plugins/ws.js","../../../../server/plugins/aw-plugins.ts","../../../../shared/config/home.mjs","../../../../server/plugins/backup.ts","../../../../server/services/workshop/logger.ts","../../../../server/services/workshop/daq/infra.ts","../../../../server/services/workshop/daq/storage/sqlite.adapter.ts","../../../../server/services/workshop/daq/storage/timescale.adapter.ts","../../../../server/services/workshop/daq/storage/index.ts","../../../../server/services/workshop/daq/bus/inproc.adapter.ts","../../../../server/services/workshop/daq/bus/mqtt.adapter.ts","../../../../server/services/workshop/daq/bus/index.ts","../../../../shared/daq-protocol.ts","../../../../server/services/workshop/daq/drivers.ts","../../../../server/services/workshop/daq/daq-templates.ts","../../../../server/services/workshop/daq/daq-node.ts","../../../../server/services/workshop/daq/daq-runtime.ts","../../../../server/services/workshop/daq/daq-node.repo.ts","../../../../server/services/workshop/daq/host-ports.ts","../../../../server/services/workshop/daq/alarm-notify.ts","../../../../server/services/workshop/daq/daq-controller.ts","../../../../server/plugins/daq.ts","../../../../server/plugins/dev-stability-guard.ts","../../../../server/services/workshop/db/retention.ts","../../../../server/plugins/retention.ts","../../../../server/plugins/security.ts","../../../../shared/config/engine.mjs","../../../../server/services/system-config.ts","../../../../server/plugins/system-config.ts","../../../../server/services/workshop/db/database.ts","../../../../server/services/workshop/db/channel.repo.ts","../../../../server/services/workshop/db/agent.repo.ts","../../../../server/services/workshop/db/channel-agent.repo.ts","../../../../server/services/workshop/db/team.repo.ts","../../../../server/services/workshop/db/team-member.repo.ts","../../../../server/services/workshop/db/channel-template.repo.ts","../../../../server/services/workshop/db/task.repo.ts","../../../../server/services/workshop/db/message.repo.ts","../../../../server/services/workshop/db/subscription.repo.ts","../../../../server/services/workshop/db/memory.repo.ts","../../../../server/services/workshop/db/user.repo.ts","../../../../server/services/workshop/db/channel-event.repo.ts","../../../../server/services/workshop/db/ops.repo.ts","../../../../server/repositories/user.repository.ts","../../../../server/services/user.service.ts","../../../../server/services/workshop/runtime/mailbox.ts","../../../../server/api/workshop/ws.ts","../../../../server/services/workshop/runtime/execution-mode.ts","../../../../server/services/workshop/agents/mock-agent.ts","../../../../server/services/workshop/agents/harness-process.ts","../../../../server/services/workshop/agents/adapters/omp-rpc-client.ts","../../../../shared/terminal-protocol.ts","../../../../server/services/workshop/agents/harness-terminal.ts","../../../../server/services/workshop/prompts/loader.ts","../../../../server/services/workshop/agents/node-bindings.repo.ts","../../../../server/services/workshop/agents/tool-approvals.ts","../../../../shared/dcw-protocol.ts","../../../../server/services/workshop/dcw/drivers.ts","../../../../server/services/workshop/dcw/dcw-templates.ts","../../../../server/services/workshop/assets/device-twin.repo.ts","../../../../server/services/workshop/dcw/dcw-node.ts","../../../../server/services/workshop/dcw/dcw-node.repo.ts","../../../../server/services/workshop/dcw/dcw-runtime.ts","../../../../server/services/workshop/dcw/dcw-product.repo.ts","../../../../server/services/workshop/dcw/dcw-recipe.repo.ts","../../../../server/services/workshop/dcw/dcw-line.repo.ts","../../../../server/services/workshop/dcw/line-run.ts","../../../../server/services/workshop/dcw/recipe-rollback.repo.ts","../../../../server/services/workshop/dcw/recipe-rollback-manager.ts","../../../../server/services/workshop/dcw/dcw-controller.ts","../../../../server/services/workshop/agents/industrial-context.ts","../../../../server/services/workshop/agents/industrial-tools.ts","../../../../server/services/workshop/agents/omp-agent.ts","../../../../server/services/workshop/agents/claude-agent.ts","../../../../server/services/workshop/agents/factory.ts","../../../../server/services/workshop/types/task.ts","../../../../server/services/workshop/runtime/agent-runtime.ts","../../../../server/services/workshop/runtime/channel-runtime.ts","../../../../server/services/workshop/runtime/scheduler-loop.ts","../../../../server/services/workshop/runtime/task-engine.ts","../../../../server/services/workshop/runtime/memory.ts","../../../../server/services/workshop/runtime/embedding-provider.ts","../../../../server/services/workshop/runtime/manager.ts","../../../../server/plugins/workshop.ts","../../../../node_modules/.pnpm/pathe@2.0.3/node_modules/pathe/dist/shared/pathe.M-eThtNZ.mjs","../../../../node_modules/.pnpm/nitropack@2.13.4_oxc-parser_b1d7d58181e96cbc69b3295f5f958520/node_modules/nitropack/dist/runtime/internal/static.mjs","../../../../server/middleware/request-log.ts","../../../../node_modules/.pnpm/nuxt-auth-utils@0.5.30_magi_25cfea03c37d60c613297752f2919dae/node_modules/nuxt-auth-utils/dist/runtime/server/api/session.delete.js","../../../../node_modules/.pnpm/nuxt-auth-utils@0.5.30_magi_25cfea03c37d60c613297752f2919dae/node_modules/nuxt-auth-utils/dist/runtime/server/api/session.get.js","../../../../node_modules/.pnpm/nitropack@2.13.4_oxc-parser_b1d7d58181e96cbc69b3295f5f958520/node_modules/nitropack/dist/runtime/internal/app.mjs","../../../../node_modules/.pnpm/nitropack@2.13.4_oxc-parser_b1d7d58181e96cbc69b3295f5f958520/node_modules/nitropack/dist/runtime/internal/lib/http-graceful-shutdown.mjs","../../../../node_modules/.pnpm/nitropack@2.13.4_oxc-parser_b1d7d58181e96cbc69b3295f5f958520/node_modules/nitropack/dist/runtime/internal/shutdown.mjs"],"names":["decode","getQuery","parse","serialize","createRouter","f","h","c","i","l","g","createError","process","mergeHeaders","crypto","flatHooks","createTask","serialTaskCaller","parallelTaskCaller","callEachWith","createHooks","Hookable","s","callHooks","nodeFetch","fetch","Headers","Headers$1","AbortController","AbortController$1","normalizeKey","defineDriver","DRIVER_NAME","dirname","fsPromises","resolve","fsp","_inlineAppConfig","createRadixRouter","__publicField","log","watch","AEP_VERSION","randomUUID","_a","DB_PATH","rows","_b","_c","_d","reqNative","sleep","REGISTRY","bad","load","normalize","singleton","require","SCHEMA_SQL","COLS","randomPassword","randomBytes","hubGlobal","hub","criteria","worker","registry","frame","save","DATA_DIR","COOLDOWN_MS","_e","fresh","partsToText","pid","seen","modeInfo","rowToTask","TaskEngineImpl","callNodeRequestHandler","fetchNodeRequestHandler","gracefulShutdown"],"mappings":"","x_google_ignoreList":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,51,52,136,137,139,140,141,142,143]}
1
+ {"version":3,"file":"nitro.mjs","sources":["../../../../node_modules/.pnpm/uncrypto@0.1.3/node_modules/uncrypto/dist/crypto.node.mjs","../../../../node_modules/.pnpm/destr@2.0.5/node_modules/destr/dist/index.mjs","../../../../node_modules/.pnpm/ufo@1.6.4/node_modules/ufo/dist/index.mjs","../../../../node_modules/.pnpm/cookie-es@1.2.3/node_modules/cookie-es/dist/index.mjs","../../../../node_modules/.pnpm/radix3@1.1.2/node_modules/radix3/dist/index.mjs","../../../../node_modules/.pnpm/defu@6.1.7/node_modules/defu/dist/defu.mjs","../../../../node_modules/.pnpm/iron-webcrypto@1.2.1/node_modules/iron-webcrypto/dist/index.js","../../../../node_modules/.pnpm/node-mock-http@1.0.5/node_modules/node-mock-http/dist/index.mjs","../../../../node_modules/.pnpm/h3@1.15.11/node_modules/h3/dist/index.mjs","../../../../node_modules/.pnpm/hookable@5.5.3/node_modules/hookable/dist/index.mjs","../../../../node_modules/.pnpm/node-fetch-native@1.6.7/node_modules/node-fetch-native/dist/native.mjs","../../../../node_modules/.pnpm/ofetch@1.5.1/node_modules/ofetch/dist/shared/ofetch.CWycOUEr.mjs","../../../../node_modules/.pnpm/ofetch@1.5.1/node_modules/ofetch/dist/node.mjs","../../../../node_modules/.pnpm/unstorage@1.17.5_db0@0.3.4_ioredis@5.11.1/node_modules/unstorage/dist/shared/unstorage.zVDD2mZo.mjs","../../../../node_modules/.pnpm/unstorage@1.17.5_db0@0.3.4_ioredis@5.11.1/node_modules/unstorage/dist/index.mjs","../../../../node_modules/.pnpm/unstorage@1.17.5_db0@0.3.4_ioredis@5.11.1/node_modules/unstorage/drivers/utils/index.mjs","../../../../node_modules/.pnpm/unstorage@1.17.5_db0@0.3.4_ioredis@5.11.1/node_modules/unstorage/drivers/utils/node-fs.mjs","../../../../node_modules/.pnpm/unstorage@1.17.5_db0@0.3.4_ioredis@5.11.1/node_modules/unstorage/drivers/fs-lite.mjs","../../../../node_modules/.pnpm/nitropack@2.13.4_oxc-parser_b1d7d58181e96cbc69b3295f5f958520/node_modules/nitropack/dist/runtime/internal/storage.mjs","../../../../node_modules/.pnpm/ohash@2.0.11/node_modules/ohash/dist/shared/ohash.D__AXeF1.mjs","../../../../node_modules/.pnpm/ohash@2.0.11/node_modules/ohash/dist/crypto/node/index.mjs","../../../../node_modules/.pnpm/nitropack@2.13.4_oxc-parser_b1d7d58181e96cbc69b3295f5f958520/node_modules/nitropack/dist/runtime/internal/hash.mjs","../../../../node_modules/.pnpm/nitropack@2.13.4_oxc-parser_b1d7d58181e96cbc69b3295f5f958520/node_modules/nitropack/dist/runtime/internal/cache.mjs","../../../../node_modules/.pnpm/klona@2.0.6/node_modules/klona/dist/index.mjs","../../../../node_modules/.pnpm/scule@1.3.0/node_modules/scule/dist/index.mjs","../../../../node_modules/.pnpm/nitropack@2.13.4_oxc-parser_b1d7d58181e96cbc69b3295f5f958520/node_modules/nitropack/dist/runtime/internal/utils.env.mjs","../../../../node_modules/.pnpm/nitropack@2.13.4_oxc-parser_b1d7d58181e96cbc69b3295f5f958520/node_modules/nitropack/dist/runtime/internal/config.mjs","../../../../node_modules/.pnpm/nitropack@2.13.4_oxc-parser_b1d7d58181e96cbc69b3295f5f958520/node_modules/nitropack/dist/runtime/internal/route-rules-utils.mjs","../../../../node_modules/.pnpm/nitropack@2.13.4_oxc-parser_b1d7d58181e96cbc69b3295f5f958520/node_modules/nitropack/dist/runtime/internal/route-rules.mjs","../../../../node_modules/.pnpm/nitropack@2.13.4_oxc-parser_b1d7d58181e96cbc69b3295f5f958520/node_modules/nitropack/dist/runtime/internal/utils.mjs","../../../../node_modules/.pnpm/@nuxt+nitro-server@4.5.2_2b2a73a5ea3a6c1cac65dd2aa61911d0/node_modules/@nuxt/nitro-server/dist/runtime/utils/error.mjs","../../../../node_modules/.pnpm/@nuxt+nitro-server@4.5.2_2b2a73a5ea3a6c1cac65dd2aa61911d0/node_modules/@nuxt/nitro-server/dist/runtime/handlers/error.mjs","../../../../node_modules/.pnpm/nitropack@2.13.4_oxc-parser_b1d7d58181e96cbc69b3295f5f958520/node_modules/nitropack/dist/runtime/internal/error/utils.mjs","../../../../node_modules/.pnpm/nitropack@2.13.4_oxc-parser_b1d7d58181e96cbc69b3295f5f958520/node_modules/nitropack/dist/runtime/internal/error/prod.mjs","../../../../node_modules/.pnpm/nuxt-auth-utils@0.5.30_magi_25cfea03c37d60c613297752f2919dae/node_modules/nuxt-auth-utils/dist/runtime/server/plugins/oauth.js","../../../../node_modules/.pnpm/hookable@6.1.1/node_modules/hookable/dist/index.mjs","../../../../node_modules/.pnpm/nitropack@2.13.4_oxc-parser_b1d7d58181e96cbc69b3295f5f958520/node_modules/nitropack/dist/runtime/internal/plugin.mjs","../../../../node_modules/.pnpm/nitropack@2.13.4_oxc-parser_b1d7d58181e96cbc69b3295f5f958520/node_modules/nitropack/dist/runtime/internal/renderer.mjs","../../../../node_modules/.pnpm/@nuxt+nitro-server@4.5.2_2b2a73a5ea3a6c1cac65dd2aa61911d0/node_modules/@nuxt/nitro-server/dist/runtime/utils/paths.mjs","../../../../server/utils/errors.ts","../../../../sdk/hooks.mjs","../../../../sdk/api.mjs","../../../../sdk/context.mjs","../../../../server/services/workshop/plugins/host.mjs","../../../../server/services/workshop/scene-events.ts","../../../../server/services/workshop/ops/ops.ts","../../../../server/utils/approval-gate.ts","../../../../server/utils/auth.ts","../../../../server/utils/config.ts","../../../../server/utils/response.ts","../../../../server/utils/validate.ts","../../../../node_modules/.pnpm/nuxt-auth-utils@0.5.30_magi_25cfea03c37d60c613297752f2919dae/node_modules/nuxt-auth-utils/dist/runtime/server/utils/session.js","../../../../node_modules/.pnpm/nuxt-auth-utils@0.5.30_magi_25cfea03c37d60c613297752f2919dae/node_modules/nuxt-auth-utils/dist/runtime/server/plugins/ws.js","../../../../server/plugins/aw-plugins.ts","../../../../shared/config/home.mjs","../../../../server/plugins/backup.ts","../../../../server/services/workshop/logger.ts","../../../../server/services/workshop/daq/infra.ts","../../../../server/services/workshop/daq/storage/sqlite.adapter.ts","../../../../server/services/workshop/daq/storage/timescale.adapter.ts","../../../../server/services/workshop/daq/storage/index.ts","../../../../server/services/workshop/daq/bus/inproc.adapter.ts","../../../../server/services/workshop/daq/bus/mqtt.adapter.ts","../../../../server/services/workshop/daq/bus/index.ts","../../../../shared/daq-protocol.ts","../../../../server/services/workshop/daq/drivers.ts","../../../../server/services/workshop/daq/daq-templates.ts","../../../../server/services/workshop/daq/daq-node.ts","../../../../server/services/workshop/daq/daq-runtime.ts","../../../../server/services/workshop/daq/daq-node.repo.ts","../../../../server/services/workshop/daq/host-ports.ts","../../../../server/services/workshop/daq/alarm-notify.ts","../../../../server/services/workshop/daq/daq-controller.ts","../../../../server/plugins/daq.ts","../../../../server/plugins/dev-stability-guard.ts","../../../../server/services/workshop/db/retention.ts","../../../../server/plugins/retention.ts","../../../../server/plugins/security.ts","../../../../shared/config/engine.mjs","../../../../server/services/system-config.ts","../../../../server/plugins/system-config.ts","../../../../server/services/workshop/db/database.ts","../../../../server/services/workshop/db/channel.repo.ts","../../../../server/services/workshop/db/agent.repo.ts","../../../../server/services/workshop/db/channel-agent.repo.ts","../../../../server/services/workshop/db/team.repo.ts","../../../../server/services/workshop/db/team-member.repo.ts","../../../../server/services/workshop/db/channel-template.repo.ts","../../../../server/services/workshop/db/task.repo.ts","../../../../server/services/workshop/db/message.repo.ts","../../../../server/services/workshop/db/subscription.repo.ts","../../../../server/services/workshop/db/memory.repo.ts","../../../../server/services/workshop/db/user.repo.ts","../../../../server/services/workshop/db/channel-event.repo.ts","../../../../server/services/workshop/db/ops.repo.ts","../../../../server/repositories/user.repository.ts","../../../../server/services/user.service.ts","../../../../server/services/workshop/runtime/mailbox.ts","../../../../server/api/workshop/ws.ts","../../../../server/services/workshop/runtime/execution-mode.ts","../../../../server/services/workshop/agents/mock-agent.ts","../../../../server/services/workshop/agents/harness-process.ts","../../../../server/services/workshop/agents/adapters/omp-rpc-client.ts","../../../../shared/terminal-protocol.ts","../../../../server/services/workshop/agents/harness-terminal.ts","../../../../server/services/workshop/prompts/loader.ts","../../../../server/services/workshop/agents/node-bindings.repo.ts","../../../../server/services/workshop/agents/tool-approvals.ts","../../../../shared/dcw-protocol.ts","../../../../server/services/workshop/dcw/drivers.ts","../../../../server/services/workshop/dcw/dcw-templates.ts","../../../../server/services/workshop/assets/device-twin.repo.ts","../../../../server/services/workshop/dcw/dcw-node.ts","../../../../server/services/workshop/dcw/dcw-node.repo.ts","../../../../server/services/workshop/dcw/dcw-runtime.ts","../../../../server/services/workshop/dcw/dcw-product.repo.ts","../../../../server/services/workshop/dcw/dcw-recipe.repo.ts","../../../../server/services/workshop/dcw/dcw-line.repo.ts","../../../../server/services/workshop/dcw/line-run.ts","../../../../server/services/workshop/dcw/recipe-rollback.repo.ts","../../../../server/services/workshop/dcw/recipe-rollback-manager.ts","../../../../server/services/workshop/dcw/dcw-controller.ts","../../../../server/services/workshop/agents/industrial-context.ts","../../../../server/services/workshop/agents/industrial-tools.ts","../../../../server/services/workshop/runtime/memory.ts","../../../../server/services/workshop/agents/omp-agent.ts","../../../../server/services/workshop/agents/claude-agent.ts","../../../../server/services/workshop/agents/factory.ts","../../../../server/services/workshop/types/task.ts","../../../../server/services/workshop/runtime/agent-runtime.ts","../../../../server/services/workshop/runtime/channel-runtime.ts","../../../../server/services/workshop/runtime/scheduler-loop.ts","../../../../server/services/workshop/runtime/task-engine.ts","../../../../server/services/workshop/runtime/embedding-provider.ts","../../../../server/services/workshop/runtime/manager.ts","../../../../server/plugins/workshop.ts","../../../../node_modules/.pnpm/pathe@2.0.3/node_modules/pathe/dist/shared/pathe.M-eThtNZ.mjs","../../../../node_modules/.pnpm/nitropack@2.13.4_oxc-parser_b1d7d58181e96cbc69b3295f5f958520/node_modules/nitropack/dist/runtime/internal/static.mjs","../../../../server/middleware/request-log.ts","../../../../node_modules/.pnpm/nuxt-auth-utils@0.5.30_magi_25cfea03c37d60c613297752f2919dae/node_modules/nuxt-auth-utils/dist/runtime/server/api/session.delete.js","../../../../node_modules/.pnpm/nuxt-auth-utils@0.5.30_magi_25cfea03c37d60c613297752f2919dae/node_modules/nuxt-auth-utils/dist/runtime/server/api/session.get.js","../../../../node_modules/.pnpm/nitropack@2.13.4_oxc-parser_b1d7d58181e96cbc69b3295f5f958520/node_modules/nitropack/dist/runtime/internal/app.mjs","../../../../node_modules/.pnpm/nitropack@2.13.4_oxc-parser_b1d7d58181e96cbc69b3295f5f958520/node_modules/nitropack/dist/runtime/internal/lib/http-graceful-shutdown.mjs","../../../../node_modules/.pnpm/nitropack@2.13.4_oxc-parser_b1d7d58181e96cbc69b3295f5f958520/node_modules/nitropack/dist/runtime/internal/shutdown.mjs"],"names":["decode","getQuery","parse","serialize","createRouter","f","h","c","i","l","g","createError","process","mergeHeaders","crypto","flatHooks","createTask","serialTaskCaller","parallelTaskCaller","callEachWith","createHooks","Hookable","s","callHooks","nodeFetch","fetch","Headers","Headers$1","AbortController","AbortController$1","normalizeKey","defineDriver","DRIVER_NAME","dirname","fsPromises","resolve","fsp","_inlineAppConfig","createRadixRouter","__publicField","log","watch","AEP_VERSION","randomUUID","_a","DB_PATH","rows","_b","_c","_d","reqNative","sleep","REGISTRY","bad","load","normalize","singleton","require","SCHEMA_SQL","COLS","randomPassword","randomBytes","hubGlobal","hub","criteria","worker","registry","frame","save","DATA_DIR","COOLDOWN_MS","_e","fresh","partsToText","pid","seen","modeInfo","rowToTask","TaskEngineImpl","callNodeRequestHandler","fetchNodeRequestHandler","gracefulShutdown"],"mappings":"","x_google_ignoreList":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,51,52,136,137,139,140,141,142,143]}
@@ -1,6 +1,6 @@
1
+ import { c as defineApiHandler, q as getRouterParam, L as readValidatedBody, M as zValidator, g as getWorkshopManager, H as AppError } from '../../../../../_/nitro.mjs';
1
2
  import { z } from 'zod';
2
3
  import { resolveUser } from '../../caller.mjs';
3
- import { c as defineApiHandler, q as getRouterParam, L as readValidatedBody, M as zValidator, g as getWorkshopManager } from '../../../../../_/nitro.mjs';
4
4
  import 'node:crypto';
5
5
  import 'node:http';
6
6
  import 'node:https';
@@ -17,14 +17,19 @@ import 'node:util';
17
17
  import 'node:module';
18
18
 
19
19
  const sendMessageSchema = z.object({
20
- toAgentId: z.string().min(1, "toAgentId \u5FC5\u586B"),
20
+ toAgentId: z.string().min(1, "toAgentId \u5FC5\u586B").optional(),
21
21
  text: z.string().min(1, "text \u5FC5\u586B"),
22
22
  fromAgentId: z.string().optional(),
23
23
  /** 人类发送者显示名(时间线 a2a.message 的发送者归属 → x-aw-from-label) */
24
24
  fromLabel: z.string().max(120).optional(),
25
25
  priority: z.enum(["immediate", "task"]).default("task"),
26
26
  /** 触发器:要求接收方回执(执行结果 + 所需内容,in_reply_to 关联) */
27
- requireReply: z.boolean().optional()
27
+ requireReply: z.boolean().optional(),
28
+ /**
29
+ * 跨 Channel 通信(仅 lead):指定目标 channel(id 或名字)→ 消息直投其 lead mailbox。
30
+ * 与 toAgentId 二选一;fromAgentId 必填且必须是本 channel 的 lead(worker 拒绝)。
31
+ */
32
+ toChannelId: z.string().optional()
28
33
  });
29
34
  const index_post = defineApiHandler(async (event) => {
30
35
  var _a, _b;
@@ -34,6 +39,23 @@ const index_post = defineApiHandler(async (event) => {
34
39
  const manager = getWorkshopManager();
35
40
  const channel = manager.getChannelForUser(channelId, user.id);
36
41
  manager.requireOwned(channel.ownerUserId, user.id, "channel");
42
+ if (body.toChannelId) {
43
+ if (body.toAgentId) {
44
+ throw new AppError(400, "BAD_REQUEST", "toChannelId \u4E0E toAgentId \u4E8C\u9009\u4E00,\u4E0D\u53EF\u540C\u65F6\u6307\u5B9A");
45
+ }
46
+ if (!body.fromAgentId) {
47
+ throw new AppError(403, "ROLE_FORBIDDEN", "\u8DE8 Channel \u901A\u4FE1\u5FC5\u987B\u4EE5\u672C channel Leader \u8EAB\u4EFD\u53D1\u9001(fromAgentId \u5FC5\u586B)");
48
+ }
49
+ const fromAgentId2 = manager.resolveChannelMember(channelId, body.fromAgentId).id;
50
+ return manager.sendCrossChannelMessage(channelId, fromAgentId2, {
51
+ toChannelId: body.toChannelId,
52
+ parts: [{ text: body.text }],
53
+ requireReply: body.requireReply
54
+ });
55
+ }
56
+ if (!body.toAgentId) {
57
+ throw new AppError(400, "BAD_REQUEST", "toAgentId \u5FC5\u586B(\u8DE8 Channel \u8BF7\u6539\u7528 toChannelId)");
58
+ }
37
59
  const target = manager.resolveChannelMember(channelId, body.toAgentId);
38
60
  let fromAgentId = body.fromAgentId;
39
61
  if (fromAgentId) {
@@ -1 +1 @@
1
- {"version":3,"file":"index3.post.mjs","sources":["../../../../../../../../server/api/workshop/channels/[id]/messages/index.post.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index3.post.mjs","sources":["../../../../../../../../server/api/workshop/channels/[id]/messages/index.post.ts"],"names":["fromAgentId"],"mappings":";;;;;;;;;;;;;;;;;;AAgBA,MAAA,iBAAA,GAAA,EAAA,MAAA,CAAA;AAAA,EACA,SAAA,EAAA,EAAA,MAAA,EAAA,CAAA,IAAA,CAAA,EAAA,wBAAA,EAAA,QAAA,EAAA;AAAA,EACA,MAAA,CAAA,CAAA,MAAA,EAAA,CAAA,GAAA,CAAA,GAAA,mBAAA,CAAA;AAAA,EACA,WAAA,EAAA,CAAA,CAAA,MAAA,EAAA,CAAA,QAAA,EAAA;AAAA;AAAA,EAEA,WAAA,CAAA,CAAA,MAAA,GAAA,GAAA,CAAA,GAAA,EAAA,QAAA,EAAA;AAAA,EACA,QAAA,EAAA,EAAA,IAAA,CAAA,CAAA,aAAA,MAAA,CAAA,CAAA,CAAA,OAAA,CAAA,MAAA,CAAA;AAAA;AAAA,EAEA,YAAA,EAAA,CAAA,CAAA,OAAA,EAAA,CAAA,QAAA,EAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAKA,WAAA,EAAA,CAAA,CAAA,MAAA,EAAA,CAAA,QAAA;AACA,CAAA,CAAA;AAEA,mBAAA,gBAAA,CAAA,OAAA,KAAA,KAAA;;AACA,EAAA,MAAA,SAAA,GAAA,cAAA,CAAA,KAAA,EAAA,IAAA,CAAA;AACA,EAAA,MAAA,IAAA,GAAA,YAAA,KAAA,CAAA;AACA,EAAA,MAAA,OAAA,MAAA,iBAAA,CAAA,KAAA,EAAA,UAAA,CAAA,iBAAA,CAAA,CAAA;AACA,EAAA,MAAA,UAAA,kBAAA,EAAA;AACA,EAAA,MAAA,OAAA,GAAA,OAAA,CAAA,iBAAA,CAAA,SAAA,EAAA,KAAA,EAAA,CAAA;AACA,EAAA,OAAA,CAAA,YAAA,CAAA,OAAA,CAAA,WAAA,EAAA,IAAA,CAAA,IAAA,SAAA,CAAA;AAGA,EAAA,IAAA,KAAA,WAAA,EAAA;AACA,IAAA,IAAA,KAAA,SAAA,EAAA;AACA,MAAA,MAAA,IAAA,QAAA,CAAA,GAAA,EAAA,aAAA,EAAA,sFAAA,CAAA;AAAA,IACA;AACA,IAAA,IAAA,CAAA,KAAA,WAAA,EAAA;AACA,MAAA,MAAA,IAAA,QAAA,CAAA,GAAA,EAAA,gBAAA,EAAA,uHAAA,CAAA;AAAA,IACA;AACA,IAAA,MAAAA,eAAA,OAAA,CAAA,oBAAA,CAAA,SAAA,EAAA,IAAA,CAAA,WAAA,CAAA,CAAA,EAAA;AACA,IAAA,OAAA,OAAA,CAAA,uBAAA,CAAA,SAAA,EAAAA,YAAAA,EAAA;AAAA,MACA,aAAA,IAAA,CAAA,WAAA;AAAA,MACA,OAAA,CAAA,EAAA,IAAA,EAAA,IAAA,CAAA,MAAA,CAAA;AAAA,MACA,cAAA,IAAA,CAAA;AAAA,KACA,CAAA;AAAA,EACA;AAEA,EAAA,IAAA,CAAA,KAAA,SAAA,EAAA;AACA,IAAA,MAAA,IAAA,QAAA,CAAA,GAAA,EAAA,aAAA,EAAA,uEAAA,CAAA;AAAA,EACA;AAGA,EAAA,MAAA,MAAA,GAAA,OAAA,CAAA,oBAAA,CAAA,SAAA,EAAA,KAAA,SAAA,CAAA;AAGA,EAAA,IAAA,cAAA,IAAA,CAAA,WAAA;AACA,EAAA,IAAA,WAAA,EAAA;AACA,IAAA,WAAA,GAAA,OAAA,CAAA,oBAAA,CAAA,SAAA,EAAA,WAAA,CAAA,CAAA,EAAA;AAAA,EACA;AAEA,EAAA,IAAA,IAAA,CAAA,aAAA,WAAA,EAAA;AACA,IAAA,OAAA,QAAA,oBAAA,CAAA;AAAA,MACA,SAAA;AAAA,MACA,WAAA;AAAA,MACA,WAAA,MAAA,CAAA,EAAA;AAAA,MACA,OAAA,CAAA,EAAA,IAAA,EAAA,IAAA,CAAA,MAAA,CAAA;AAAA,MACA,cAAA,IAAA,CAAA,YAAA;AAAA;AAAA,MAEA,SAAA,EAAA,CAAA,EAAA,GAAA,IAAA,CAAA,SAAA,KAAA,IAAA,GAAA,EAAA,GAAA,IAAA,CAAA;AAAA,KACA,CAAA;AAAA,EACA;AAEA,EAAA,IAAA,WAAA,EAAA;AACA,IAAA,OAAA,OAAA,CAAA,OAAA,CAAA,SAAA,EAAA,WAAA,EAAA;AAAA,MACA,WAAA,MAAA,CAAA,EAAA;AAAA,MACA,OAAA,CAAA,EAAA,IAAA,EAAA,IAAA,CAAA,MAAA,CAAA;AAAA,MACA,QAAA,EAAA;AAAA,QACA,mBAAA,EAAA,MAAA;AAAA,QACA,GAAA,IAAA,CAAA,YAAA,GAAA,EAAA,oBAAA,EAAA,MAAA,KAAA;AAAA;AACA,KACA,CAAA;AAAA,EACA;AACA,EAAA,OAAA,QAAA,oBAAA,CAAA;AAAA,IACA,SAAA;AAAA,IACA,WAAA,EAAA,EAAA;AAAA,IACA,WAAA,MAAA,CAAA,EAAA;AAAA,IACA,OAAA,CAAA,EAAA,IAAA,EAAA,IAAA,CAAA,MAAA,CAAA;AAAA,IACA,cAAA,IAAA,CAAA,YAAA;AAAA,IACA,SAAA,EAAA,CAAA,EAAA,GAAA,IAAA,CAAA,SAAA,KAAA,IAAA,GAAA,EAAA,GAAA,IAAA,CAAA;AAAA,GACA,CAAA;AACA,CAAA,CAAA;;;;"}
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentworkshop-prod",
3
- "version": "0.5.5",
3
+ "version": "0.5.6",
4
4
  "type": "module",
5
5
  "private": true,
6
6
  "dependencies": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentworkshop",
3
- "version": "0.5.5",
3
+ "version": "0.5.6",
4
4
  "type": "module",
5
5
  "description": "AgentWorkShop 软件开发系统 - 基于 Nuxt 4 的配置驱动运行范式",
6
6
  "license": "PolyForm-Noncommercial-1.0.0",
@@ -0,0 +1,157 @@
1
+ /**
2
+ * 跨 Channel 通信端到端验证(针对运行中的环境,默认 http://127.0.0.1:3000)。
3
+ * 覆盖:lead→异 channel lead 投递(metadata 盖章/落对方 mailbox)→ mock lead 消费并
4
+ * 自动回执(跨 channel 回信)→ 回信到达源 channel lead → 权限(worker 拒)→
5
+ * 边界(自指/停用/无 lead channel)。
6
+ * 运行: node scripts/_dbg-cross-channel-e2e.mjs (AW_BASE 可覆盖目标)
7
+ */
8
+ const ROOT = process.env.AW_BASE ?? 'http://127.0.0.1:3000'
9
+ let TOKEN = process.env.AW_E2E_TOKEN ?? ''
10
+ const H = () => ({ authorization: `Bearer ${TOKEN}`, 'content-type': 'application/json' })
11
+ const sleep = (ms) => new Promise(r => setTimeout(r, ms))
12
+ let failures = 0
13
+ const check = (name, ok, detail = '') => {
14
+ console.log(` ${ok ? 'PASS' : 'FAIL'} ${name}${detail ? ` — ${detail}` : ''}`)
15
+ if (!ok) failures++
16
+ }
17
+ const fail = (m) => { console.error('FATAL:', m); process.exit(1) }
18
+
19
+ async function api(method, path, body) {
20
+ const res = await fetch(ROOT + path, { method, headers: H(), body: body !== undefined ? JSON.stringify(body) : undefined })
21
+ const json = await res.json().catch(() => ({}))
22
+ return { status: res.status, ...json }
23
+ }
24
+ const jpost = (u, b) => api('POST', u, b ?? {})
25
+ const jget = (u) => api('GET', u)
26
+ const cleanup = []
27
+ const tag = Math.random().toString(36).slice(2, 8)
28
+
29
+ async function deployTeam(channelName, extraWorkers = []) {
30
+ const chRes = (await jpost('/api/workshop/channels', { name: channelName, description: '跨Channel验证' })).data
31
+ cleanup.push(['channel', chRes.channelId])
32
+ const team = (await jpost('/api/workshop/teams', { name: channelName + '-组', description: '跨Channel验证' })).data
33
+ cleanup.push(['team', team.id])
34
+ // 成员先入队再一次 deploy(重复 deploy 不会同步新增成员)
35
+ await jpost(`/api/workshop/teams/${team.id}/members`, { agentId: 'tpl-default-lead', role: 'lead' })
36
+ for (const w of extraWorkers) {
37
+ await jpost(`/api/workshop/teams/${team.id}/members`, { agentId: w.id, role: 'worker' })
38
+ }
39
+ await jpost(`/api/workshop/teams/${team.id}/deploy`, { channelId: chRes.channelId })
40
+ const agents = (await jget(`/api/workshop/channels/${chRes.channelId}/agents`)).data
41
+ const lead = agents.find(a => a.role === 'lead')
42
+ const worker = agents.find(a => a.role === 'worker')
43
+ cleanup.push(['channel-agent', `${chRes.channelId}:${lead?.id}`])
44
+ if (worker) cleanup.push(['channel-agent', `${chRes.channelId}:${worker.id}`])
45
+ return { channelId: chRes.channelId, lead, worker, teamId: team.id }
46
+ }
47
+
48
+ async function main() {
49
+ console.log('━━━ 0. 用户注册 ━━━')
50
+ const reg = await jpost('/api/workshop/users/register', { name: 'xcc-' + tag })
51
+ TOKEN = reg.data?.token
52
+ if (!TOKEN) fail('用户注册失败: ' + JSON.stringify(reg).slice(0, 120))
53
+ check('用户注册并取得 token', !!TOKEN)
54
+
55
+ // ===== 1. 两个团队:西线(lead mock + worker mock)/ 东线(lead mock)=====
56
+ console.log('\n━━━ 1. 双 channel 部署 ━━━')
57
+ const workerTpl = (await jpost('/api/workshop/agents', { name: '西线worker-' + tag, harness: 'mock', config: {} })).data
58
+ cleanup.push(['agent-tpl', workerTpl.id])
59
+ const west = await deployTeam('西线团队-' + tag, [workerTpl])
60
+ check('西线 channel + mock lead 就绪', !!west.channelId && !!west.lead?.id)
61
+ const east = await deployTeam('东线团队-' + tag)
62
+ check('东线 channel + mock lead 就绪', !!east.channelId && !!east.lead?.id)
63
+ const westWorker = west.worker
64
+ check('西线 worker 就绪(权限反证用)', !!westWorker?.id)
65
+
66
+ // ===== 2. 跨 Channel 发送(REST,lead 身份)=====
67
+ console.log('\n━━━ 2. 跨 Channel 投递(lead → 对方 lead)━━━')
68
+ const ask = '东线请注意:西线请求支援——请分析你们 channel 的负载情况,并把结论回执给我。'
69
+ const sent = await jpost(`/api/workshop/channels/${west.channelId}/messages`, {
70
+ toChannelId: east.channelId,
71
+ fromAgentId: west.lead.id,
72
+ text: ask,
73
+ requireReply: true,
74
+ })
75
+ check('跨 Channel 发送成功(回执含目标 channel/lead)',
76
+ sent.status === 200 && sent.data?.toChannelId === east.channelId && sent.data?.toLeadAgentId === east.lead.id,
77
+ `messageId=${String(sent.data?.messageId ?? '').slice(0, 8)} toChannel=${String(sent.data?.toChannelName ?? '')}`)
78
+ const crossMsgId = sent.data?.messageId
79
+ cleanup.push(['cross-message', crossMsgId])
80
+
81
+ // 落库断言:消息出现在东线历史,盖章齐全,收件人=东线 lead
82
+ const eastMsgs = (await jget(`/api/workshop/channels/${east.channelId}/messages?limit=20`)).data
83
+ const list = Array.isArray(eastMsgs) ? eastMsgs : eastMsgs?.messages ?? []
84
+ const delivered = list.find(m => m.id === crossMsgId)
85
+ const meta = delivered?.metadata ?? {}
86
+ check('东线 mailbox 可见该消息(收件人=东线 lead)', !!delivered && delivered.toAgentId === east.lead.id)
87
+ check('跨 Channel 盖章齐全(cross-channel/from-channel/from-label)',
88
+ meta['x-aw-cross-channel'] === 'true'
89
+ && meta['x-aw-from-channel'] === west.channelId
90
+ && String(meta['x-aw-from-label'] ?? '').includes('西线团队'),
91
+ `label=${String(meta['x-aw-from-label'] ?? '')}`)
92
+
93
+ // ===== 3. 东线 lead 消费并自动回执(跨 channel 回信到西线 lead)=====
94
+ console.log('\n━━━ 3. 对方 lead 消费并回信(闭环)━━━')
95
+ let reply = null
96
+ for (let i = 0; i < 20; i++) {
97
+ await sleep(1500)
98
+ const westMsgs = (await jget(`/api/workshop/channels/${west.channelId}/messages?limit=20`)).data
99
+ const wlist = Array.isArray(westMsgs) ? westMsgs : westMsgs?.messages ?? []
100
+ reply = wlist.find(m => m.metadata?.['x-aw-in-reply-to'] === crossMsgId
101
+ && m.metadata?.['x-aw-cross-channel'] === 'true'
102
+ && m.toAgentId === west.lead.id)
103
+ if (reply) break
104
+ }
105
+ check('东线 lead 自动回信到达西线 lead(in_reply_to 关联)', !!reply,
106
+ reply ? `text=${String(reply.parts?.[0]?.text ?? '').slice(0, 50)}…` : '30s 内未收到回信')
107
+ if (reply) cleanup.push(['cross-message', reply.id])
108
+
109
+ // 回信已被西线 lead 消费?(mock 收到无需回执的信件仅登记;此处只验投递与可见性)
110
+
111
+ // ===== 4. 权限:worker 跨 Channel 被拒 =====
112
+ console.log('\n━━━ 4. 权限反证 ━━━')
113
+ const denied = await jpost(`/api/workshop/channels/${west.channelId}/messages`, {
114
+ toChannelId: east.channelId,
115
+ fromAgentId: westWorker.id,
116
+ text: 'worker 试图跨 Channel(应被拒)',
117
+ })
118
+ check('worker 跨 Channel 被拒(403 ROLE_FORBIDDEN)',
119
+ denied.status === 403 && String(denied.message ?? '').includes('Leader'),
120
+ `status=${denied.status} msg=${String(denied.message ?? '').slice(0, 60)}`)
121
+
122
+ // 无 fromAgentId(人类身份)跨 Channel 同样拒绝
123
+ const anon = await jpost(`/api/workshop/channels/${west.channelId}/messages`, {
124
+ toChannelId: east.channelId,
125
+ text: '匿名跨 Channel(应被拒)',
126
+ })
127
+ check('无 Leader 身份被拒(403)', anon.status === 403, `status=${anon.status}`)
128
+
129
+ // ===== 5. 边界:自指 / 停用 / 不存在 =====
130
+ console.log('\n━━━ 5. 边界用例 ━━━')
131
+ const selfRef = await jpost(`/api/workshop/channels/${west.channelId}/messages`, {
132
+ toChannelId: west.channelId, fromAgentId: west.lead.id, text: 'self',
133
+ })
134
+ check('目标=本 channel 被拒(404)', selfRef.status === 404, `status=${selfRef.status}`)
135
+ const ghost = await jpost(`/api/workshop/channels/${west.channelId}/messages`, {
136
+ toChannelId: 'ch-not-exists-' + tag, fromAgentId: west.lead.id, text: 'ghost',
137
+ })
138
+ check('目标不存在被拒(404)', ghost.status === 404, `status=${ghost.status}`)
139
+
140
+ // ===== 清理 =====
141
+ console.log('\n━━━ 清理 ━━━')
142
+ for (const [kind, id] of cleanup.reverse()) {
143
+ if (kind === 'channel') await api('DELETE', `/api/workshop/channels/${id}`)
144
+ else if (kind === 'team') await api('DELETE', `/api/workshop/teams/${id}`)
145
+ else if (kind === 'agent-tpl') await api('DELETE', `/api/workshop/agents/${id}`)
146
+ else if (kind === 'channel-agent') {
147
+ const [cid, aid] = String(id).split(':')
148
+ if (cid && aid) await api('DELETE', `/api/workshop/channels/${cid}/agents/${aid}`)
149
+ }
150
+ }
151
+ console.log('清理完成')
152
+
153
+ console.log(failures === 0 ? '\nE2E ALL PASS' : `\nE2E ${failures} FAILED`)
154
+ if (failures > 0) process.exit(1)
155
+ }
156
+
157
+ main().catch((e) => { console.error(e); process.exit(1) })
@@ -0,0 +1,176 @@
1
+ /**
2
+ * 上下文治理环测试(假 RPC 客户端,零真实子进程):
3
+ * 70% 门控 / get_state 复查 / compact→compaction_end 等待 / legacy 降级 /
4
+ * 压缩事件分支 harvest / 被动 usage 透出 / 总开关与最小间隔。
5
+ * 运行: npx tsx --tsconfig .nuxt/tsconfig.server.json scripts/test-context-governor.ts
6
+ */
7
+ import { OmpRpcAgentImpl } from '../server/services/workshop/agents/omp-agent'
8
+
9
+ let failures = 0
10
+ function check(name: string, ok: boolean, detail = ''): void {
11
+ console.log(` ${ok ? 'PASS' : 'FAIL'} ${name}${detail ? ` — ${detail}` : ''}`)
12
+ if (!ok) failures += 1
13
+ }
14
+
15
+ type Frame = Record<string, unknown>
16
+
17
+ /** 假 omp RPC 客户端:协议面仿真(命令应答/事件订阅/被动 usage) */
18
+ class FakeOmpClient {
19
+ alive = true
20
+ streaming = false
21
+ statsOk = true
22
+ compactOk = true
23
+ usageTokens = 0
24
+ contextWindow = 1000
25
+ autoCompact: boolean | null = null
26
+ sent: Array<Record<string, unknown>> = []
27
+ private listeners = new Set<(e: Frame) => void>()
28
+
29
+ onEvent(fn: (e: Frame) => void): () => void {
30
+ this.listeners.add(fn)
31
+ return () => this.listeners.delete(fn)
32
+ }
33
+
34
+ emit(e: Frame): void {
35
+ for (const fn of this.listeners) fn(e)
36
+ }
37
+
38
+ async send(cmd: Record<string, unknown>): Promise<{ success: boolean, data?: unknown }> {
39
+ this.sent.push(cmd)
40
+ const type = cmd.type as string
41
+ if (type === 'get_session_stats') {
42
+ if (!this.statsOk) throw new Error('omp RPC 命令失败: get_session_stats 未知命令')
43
+ return { success: true, data: { contextUsage: { tokens: this.usageTokens, contextWindow: this.contextWindow, percent: this.usageTokens / this.contextWindow } } }
44
+ }
45
+ if (type === 'get_state') {
46
+ return { success: true, data: { isStreaming: this.streaming, isCompacting: false, sessionId: 'sess-1', model: { contextWindow: this.contextWindow } } }
47
+ }
48
+ if (type === 'compact') {
49
+ if (!this.compactOk) throw new Error('omp RPC 命令失败: compact 未知命令')
50
+ const summary = '压缩摘要:完成任务A;未竟:验证B'
51
+ setTimeout(() => {
52
+ this.emit({ type: 'compaction_end', result: { summary, tokensBefore: this.usageTokens, tokensAfter: 30000 }, reason: 'manual' })
53
+ }, 10)
54
+ return { success: true, data: {} }
55
+ }
56
+ if (type === 'set_auto_compaction') {
57
+ this.autoCompact = cmd.enabled as boolean
58
+ return { success: true }
59
+ }
60
+ return { success: true }
61
+ }
62
+
63
+ getContextUsage(): { tokens: number, contextWindow: number, percent: number } {
64
+ return { tokens: this.usageTokens, contextWindow: this.contextWindow, percent: this.usageTokens / this.contextWindow }
65
+ }
66
+
67
+ setContextWindow(n: number): void {
68
+ this.contextWindow = n
69
+ }
70
+
71
+ onHostToolCall(_fn: unknown): void {}
72
+ }
73
+
74
+ /** 装配:真实 OmpRpcAgentImpl + 注入假客户端/假 workspace */
75
+ function assemble(): { impl: OmpRpcAgentImpl, client: FakeOmpClient, harvested: Array<Record<string, unknown>> } {
76
+ const impl = new OmpRpcAgentImpl({ agentId: 'a1', name: 'A', role: 'worker', channelId: 'ch1' })
77
+ const client = new FakeOmpClient()
78
+ const harvested: Array<Record<string, unknown>> = []
79
+ const box = impl as unknown as Record<string, unknown>
80
+ box.client = client
81
+ box.workspace = {
82
+ recordSessionMemory: async (i: Record<string, unknown>) => {
83
+ harvested.push(i)
84
+ },
85
+ }
86
+ return { impl, client, harvested }
87
+ }
88
+
89
+ const gate = (impl: OmpRpcAgentImpl, reason = 'test'): Promise<void> =>
90
+ (impl as unknown as Record<string, unknown>).contextGate(reason) as Promise<void>
91
+
92
+ process.env.AW_OMP_COMPACT_THRESHOLD = '0.7'
93
+ process.env.AW_OMP_COMPACT_MIN_INTERVAL_MS = '300000'
94
+ process.env.AW_OMP_COMPACT_WAIT_MS = '5000'
95
+
96
+ console.log('\n--- 门控基础路径 ---')
97
+ {
98
+ process.env.AW_OMP_COMPACT_ENABLED = '1'
99
+ const { impl, client, harvested } = assemble()
100
+ client.usageTokens = 500 // 50% < 70%
101
+ await gate(impl)
102
+ check('低于阈值不触发 compact', !client.sent.some(c => c.type === 'compact'), `sent=${client.sent.map(c => c.type)}`)
103
+
104
+ client.usageTokens = 850 // 85% ≥ 70%
105
+ await gate(impl)
106
+ check('达阈值发起 compact', client.sent.some(c => c.type === 'compact'))
107
+ check('compact 前先复查 get_state', client.sent.indexOf('get_state') !== -1 || client.sent.some(c => c.type === 'get_state'))
108
+ await new Promise(r => setTimeout(r, 50))
109
+ check('compaction_end 摘要 harvest 入库', harvested.length === 1 && harvested[0]!.summary === '压缩摘要:完成任务A;未竟:验证B', JSON.stringify(harvested))
110
+ check('harvest 携带 token 元信息', harvested[0]!.tokensBefore === 850 && harvested[0]!.tokensAfter === 30000)
111
+
112
+ // 最小间隔:压缩后立即再 gate 不应二次 compact
113
+ client.usageTokens = 950
114
+ await gate(impl)
115
+ check('最小间隔防振荡(不再 compact)', client.sent.filter(c => c.type === 'compact').length === 1)
116
+ }
117
+
118
+ console.log('\n--- 安全防线 ---')
119
+ {
120
+ // get_state 复查:流式中绝不压缩
121
+ const { impl, client } = assemble()
122
+ client.usageTokens = 900
123
+ client.streaming = true
124
+ await gate(impl)
125
+ check('isStreaming=true 时不发起 compact', !client.sent.some(c => c.type === 'compact'))
126
+
127
+ // 总开关
128
+ process.env.AW_OMP_COMPACT_ENABLED = '0'
129
+ const g2 = assemble()
130
+ g2.client.usageTokens = 900
131
+ await gate(g2.impl)
132
+ check('总开关关闭不压缩', !g2.client.sent.some(c => c.type === 'compact'))
133
+ process.env.AW_OMP_COMPACT_ENABLED = '1'
134
+
135
+ // legacy 降级:compact 未知命令 → 标记后不再尝试
136
+ const g3 = assemble()
137
+ g3.client.usageTokens = 900
138
+ g3.client.compactOk = false
139
+ await gate(g3.impl)
140
+ const box3 = g3.impl as unknown as Record<string, unknown>
141
+ check('未知命令 → legacy 标记', box3.compactLegacy === true)
142
+ g3.client.usageTokens = 980
143
+ await gate(g3.impl)
144
+ check('legacy 后续回合不再发 compact', g3.client.sent.filter(c => c.type === 'compact').length === 1)
145
+ }
146
+
147
+ console.log('\n--- 事件分支与状态透出 ---')
148
+ {
149
+ const { impl, client, harvested } = assemble()
150
+ // 回合中途原生压缩(compaction_start/end 事件):不污染事件流 + harvest
151
+ const map = (impl as unknown as Record<string, (e: Frame) => Frame[]>).mapOmpEvent.bind(impl)
152
+ const startOut = map({ type: 'compaction_start' }, undefined)
153
+ const endOut = map({ type: 'compaction_end', result: { summary: '原生阈值压缩摘要', tokensBefore: 900 }, reason: 'threshold' }, undefined)
154
+ const settledOut = map({ type: 'agent_settled' }, undefined)
155
+ check('压缩事件映射为空(不污染 AgentEvent 流)', startOut.length === 0 && endOut.length === 0 && settledOut.length === 0)
156
+ await new Promise(r => setTimeout(r, 20))
157
+ check('原生压缩摘要同样 harvest', harvested.some(h => h.summary === '原生阈值压缩摘要'))
158
+
159
+ // 被动 usage 透出 getContextStats
160
+ client.usageTokens = 420
161
+ const stats = (impl as unknown as Record<string, () => unknown>).getContextStats()
162
+ check('getContextStats 透出用量与占比', JSON.stringify(stats) === JSON.stringify({ usedTokens: 420, contextWindow: 1000, percent: 0.42, compacting: false }), JSON.stringify(stats))
163
+
164
+ // 双路去重:同摘要 60s 内只入库一次
165
+ map({ type: 'compaction_end', result: { summary: '原生阈值压缩摘要' }, reason: 'threshold' }, undefined)
166
+ await new Promise(r => setTimeout(r, 20))
167
+ check('同摘要双达去重(60s 窗口)', harvested.filter(h => h.summary === '原生阈值压缩摘要').length === 1)
168
+
169
+ // onTurnSettled 复用 gate(自守卫不抛错)
170
+ client.usageTokens = 100
171
+ await impl.onTurnSettled()
172
+ check('onTurnSettled 低用量安全返回', true)
173
+ }
174
+
175
+ console.log(failures === 0 ? '\nALL PASS' : `\n${failures} FAILED`)
176
+ process.exit(failures === 0 ? 0 : 1)