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.
- package/.AgentWorkShop/prompts/compaction-hints.md +9 -0
- package/.AgentWorkShop/prompts/host-tools.json +664 -630
- package/.AgentWorkShop/prompts/peer-reply-cross-channel.md +10 -0
- package/.AgentWorkShop/prompts/system-manual.md +6 -1
- package/.output/.AgentWorkShop/prompts/compaction-hints.md +9 -0
- package/.output/.AgentWorkShop/prompts/host-tools.json +664 -630
- package/.output/.AgentWorkShop/prompts/peer-reply-cross-channel.md +10 -0
- package/.output/.AgentWorkShop/prompts/system-manual.md +6 -1
- package/.output/nitro.json +1 -1
- package/.output/public/_nuxt/builds/latest.json +1 -1
- package/.output/public/_nuxt/builds/meta/d50c6ec2-801c-4ba2-97d8-a4db401b702c.json +1 -0
- package/.output/server/chunks/_/nitro.mjs +1920 -1211
- package/.output/server/chunks/_/nitro.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/channels/_id/index3.post.mjs +25 -3
- package/.output/server/chunks/routes/api/workshop/channels/_id/index3.post.mjs.map +1 -1
- package/.output/server/package.json +1 -1
- package/package.json +1 -1
- package/scripts/_dbg-cross-channel-e2e.mjs +157 -0
- package/scripts/test-context-governor.ts +176 -0
- package/scripts/test-memory-brief-chronicle.ts +180 -0
- package/scripts/test-memory-dynamic.ts +3 -1
- package/scripts/test-memory-rrf-mmr.ts +114 -0
- package/server/api/workshop/channels/[id]/messages/index.post.ts +26 -1
- package/server/api/workshop/ws.ts +1 -0
- package/server/data/daqs.json +35 -13
- package/server/data/dcw-lines.json +14 -0
- package/server/data/dcw-products.json +14 -0
- package/server/data/dcw-recipes.json +28 -0
- package/server/data/dcw-rollback.json +122 -1
- package/server/data/dcw-runs.json +54 -36
- package/server/data/dcw-writes.json +60 -0
- package/server/data/dcws.json +42 -0
- package/server/data/line-runs.json +32 -22
- package/server/services/workshop/agents/adapters/omp-rpc-client.ts +65 -0
- package/server/services/workshop/agents/agent-interface.ts +26 -1
- package/server/services/workshop/agents/mock-agent.ts +12 -0
- package/server/services/workshop/agents/omp-agent.ts +277 -8
- package/server/services/workshop/db/database.ts +16 -1
- package/server/services/workshop/db/memory.repo.ts +22 -2
- package/server/services/workshop/prompts/loader.ts +6 -5
- package/server/services/workshop/runtime/agent-runtime.ts +52 -6
- package/server/services/workshop/runtime/channel-runtime.ts +14 -6
- package/server/services/workshop/runtime/manager.ts +192 -3
- package/server/services/workshop/runtime/memory.ts +313 -78
- package/server/services/workshop/types/task.ts +14 -0
- 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":";;;;;;;;;;;;;;;;;;AAgBA,
|
|
1
|
+
{"version":3,"file":"index3.post.mjs","sources":["../../../../../../../../server/api/workshop/channels/[id]/messages/index.post.ts"],"names":["fromAgentId"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -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)
|