@inneranimalmedia/agentsam-sdk 2.6.7 → 2.6.9
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/README.md +37 -0
- package/apps/README.md +25 -0
- package/apps/cad-creator/shared/cad/package.json +1 -1
- package/apps/client-cms-editor/backend/package.json +4 -6
- package/apps/client-cms-editor/frontend/package.json +6 -8
- package/apps/client-cms-editor/frontend/tsconfig.json +27 -8
- package/apps/client-cms-editor/package.json +1 -1
- package/apps/client-cms-editor/shared/cms/package.json +4 -6
- package/docs/LOCAL_ENGINE_COMPUTE_AUDIT_PLAN.md +299 -0
- package/docs/REPO_FILE_MAP.txt +132 -0
- package/migrations/d1/0018_goap_control_plane_remaster.sql +40 -0
- package/migrations/d1/0019_agentsam_agent_run_plan_todo.sql +14 -0
- package/migrations/d1/README_PORTABLE_CONTROL_PLANE.md +20 -9
- package/migrations/runtime/0002_goap_blackboard_v1.sql +15 -0
- package/migrations/runtime/0004_agent_run_plan_linkage.sql +8 -0
- package/native/agentsam-machine/cli/Cargo.toml +8 -1
- package/native/agentsam-machine/cli/README.md +21 -0
- package/native/agentsam-machine/core/Cargo.toml +7 -0
- package/native/agentsam-machine/core/README.md +14 -0
- package/native/agentsam-machine/core/build.rs +33 -0
- package/native/agentsam-machine/core/contracts/source-types.v1.json +353 -0
- package/native/agentsam-machine/core/src/lib.rs +6 -0
- package/native/agentsam-machine/core/src/source_types.rs +2 -2
- package/package.json +31 -10
- package/packages/agentsam-brand/package.json +1 -1
- package/packages/agentsam-contracts/package.json +71 -20
- package/packages/agentsam-contracts/scripts/build.mjs +18 -0
- package/packages/agentsam-contracts/test/contracts.test.mjs +4 -1
- package/packages/agentsam-contracts/test/repository.test.mjs +4 -1
- package/packages/agentsam-contracts/tsconfig.build.json +10 -0
- package/packages/agentsam-errors/package.json +3 -2
- package/packages/agentsam-errors/src/index.js +1 -0
- package/packages/agentsam-errors/src/tool.js +56 -0
- package/packages/agentsam-errors/test/tool.test.mjs +58 -0
- package/packages/agentsam-goap/README.md +52 -0
- package/packages/agentsam-goap/package.json +37 -0
- package/packages/agentsam-goap/src/adapters/d1-sqlite.js +570 -0
- package/packages/agentsam-goap/src/adapters/memory.js +199 -0
- package/packages/agentsam-goap/src/contracts.js +226 -0
- package/packages/agentsam-goap/src/control-plane.js +112 -0
- package/packages/agentsam-goap/src/errors.js +157 -0
- package/packages/agentsam-goap/src/index.js +5 -0
- package/packages/agentsam-goap/src/world.js +202 -0
- package/packages/agentsam-goap/test/goap-control-plane.test.mjs +245 -0
- package/packages/agentsam-goap/test/world.test.mjs +79 -0
- package/packages/agentsam-knowledge/package.json +3 -2
- package/packages/agentsam-nav/package.json +1 -1
- package/packages/agentsam-queue-control/package.json +1 -1
- package/packages/agentsam-rapid-rust/src/main.rs +1 -0
- package/packages/agentsam-repository/package.json +3 -2
- package/packages/agentsam-repository/src/goap.js +13 -14
- package/packages/agentsam-repository/src/tickets.js +15 -22
- package/packages/agentsam-repository/test/goap-tickets-workspace-state.test.mjs +19 -8
- package/packages/agentsam-vault/package.json +8 -5
- package/packages/agentsam-workbench/package.json +44 -17
- package/packages/connectors/cloudflare/package.json +4 -2
- package/packages/heuristic-theme/package.json +1 -1
- package/packages/identity/package.json +4 -3
- package/packages/identity/tests/lane1-packed-consumer.test.mjs +10 -2
- package/packages/providers/completeful/package.json +1 -1
- package/packages/theme-church-site/README.md +2 -2
- package/packages/theme-church-site/package.json +3 -4
- package/packages/theme-church-site/src/index.js +1 -1
- package/packages/theme-church-site/test/theme.test.mjs +1 -1
- package/packages/theme-companions-site/README.md +2 -2
- package/packages/theme-companions-site/package.json +3 -4
- package/packages/theme-companions-site/src/index.js +1 -1
- package/packages/theme-companions-site/test/theme.test.mjs +1 -1
- package/packages/theme-floors-site/README.md +2 -2
- package/packages/theme-floors-site/package.json +3 -4
- package/packages/theme-floors-site/src/index.js +1 -1
- package/packages/theme-floors-site/test/theme.test.mjs +1 -1
- package/packages/theme-fuelnfree-site/README.md +2 -2
- package/packages/theme-fuelnfree-site/package.json +3 -4
- package/packages/theme-fuelnfree-site/src/index.js +1 -1
- package/packages/theme-fuelnfree-site/test/theme.test.mjs +1 -1
- package/packages/theme-handyman-site/README.md +2 -2
- package/packages/theme-handyman-site/package.json +3 -4
- package/packages/theme-handyman-site/src/index.js +1 -1
- package/packages/theme-handyman-site/test/theme.test.mjs +1 -1
- package/packages/theme-insurance-site/README.md +2 -2
- package/packages/theme-insurance-site/package.json +3 -4
- package/packages/theme-insurance-site/src/index.js +1 -1
- package/packages/theme-insurance-site/test/theme.test.mjs +1 -1
- package/packages/theme-scenes/package.json +1 -1
- package/packages/theme-shinshu-site/README.md +2 -2
- package/packages/theme-shinshu-site/package.json +3 -4
- package/packages/theme-shinshu-site/src/index.js +1 -1
- package/packages/theme-shinshu-site/test/theme.test.mjs +1 -1
- package/packages/work-graph/package.json +3 -2
- package/protocol/local-engine/benchmark.v1.schema.json +14 -0
- package/protocol/local-engine/engine.v1.schema.json +17 -0
- package/python/agentsam_sdk/repository/intelligence/discovery.py +27 -2
- package/python/agentsam_sdk/repository/intelligence/git.py +4 -0
- package/python/tests/test_repository_intelligence.py +30 -0
- package/src/cli/command-catalog.js +3 -1
- package/src/cli.js +20 -1
- package/src/commands/app.js +10 -0
- package/src/commands/engine.js +10 -0
- package/src/commands/goap-world.js +134 -0
- package/src/commands/goap.js +11 -4
- package/src/commands/machine-binary.js +33 -27
- package/src/commands/machine-runtime.js +266 -0
- package/src/commands/machine.js +155 -51
- package/src/commands/package.js +537 -0
- package/src/commands/plan-ledger.js +370 -0
- package/src/commands/plan.js +183 -0
- package/src/commands/runtime.js +25 -10
- package/src/commands/setup.js +30 -6
- package/src/commands/skill.js +78 -17
- package/src/commands/terminal.js +20 -8
- package/src/errors/contract.js +4 -4
- package/src/errors/diagnostic.js +1 -1
- package/src/errors/index.js +1 -1
- package/src/index.js +20 -0
- package/src/indexing/ingest/materials.js +237 -30
- package/src/knowledge/source.js +1 -1
- package/src/lib/setup/runtime.js +4 -2
- package/src/lib/slash-commands.js +1 -1
- package/src/local/runtime-store.js +24 -2
- package/src/local/sqlite.js +17 -0
- package/src/local-engine/assets.js +37 -0
- package/src/local-engine/audit.js +133 -0
- package/src/local-engine/benchmark.js +26 -0
- package/src/local-engine/contracts.js +101 -0
- package/src/local-engine/engines.js +142 -0
- package/src/local-engine/index.js +18 -0
- package/src/local-engine/runtime.js +39 -0
- package/src/sam/operations/package-audit.js +41 -0
- package/src/sam/seed.js +2 -0
- package/skills/grok-auth/SKILL.md +0 -110
- package/skills/grok-auth/agentsam.skill.json +0 -25
- package/skills/grok-auth/references/grok-identity.md +0 -64
- package/skills/grok-auth/references/per-user-data.md +0 -49
- package/skills/grok-auth/references/prewired-and-env.md +0 -54
- package/skills/grok-auth/references/session-ui.md +0 -133
- package/skills/grok-auth/references/sign-in-methods.md +0 -55
- package/skills/grok-auth/references/wiring.md +0 -71
- package/skills/grok-building-games/SKILL.md +0 -213
- package/skills/grok-building-games/agentsam.skill.json +0 -25
- package/skills/grok-building-games/references/3d-libs.md +0 -64
- package/skills/grok-building-games/references/ai-pathfinding.md +0 -122
- package/skills/grok-building-games/references/audio.md +0 -129
- package/skills/grok-building-games/references/babylon.md +0 -202
- package/skills/grok-building-games/references/collision-physics.md +0 -122
- package/skills/grok-building-games/references/ecs-architecture.md +0 -111
- package/skills/grok-building-games/references/game-feel-juice.md +0 -110
- package/skills/grok-building-games/references/genres/board-card-chess.md +0 -89
- package/skills/grok-building-games/references/genres/endless-runner.md +0 -83
- package/skills/grok-building-games/references/genres/fps.md +0 -105
- package/skills/grok-building-games/references/genres/platformer-2d.md +0 -97
- package/skills/grok-building-games/references/genres/puzzle-match3-tetris.md +0 -131
- package/skills/grok-building-games/references/genres/racing-kart.md +0 -106
- package/skills/grok-building-games/references/genres/topdown-twin-stick.md +0 -97
- package/skills/grok-building-games/references/genres/tower-defense.md +0 -84
- package/skills/grok-building-games/references/genres/voxel-minecraft.md +0 -89
- package/skills/grok-building-games/references/input.md +0 -139
- package/skills/grok-building-games/references/phaser.md +0 -277
- package/skills/grok-building-games/references/procedural-generation.md +0 -141
- package/skills/grok-building-games/references/save-persistence.md +0 -108
- package/skills/grok-building-games/references/threejs-foundational.md +0 -148
- package/skills/grok-controls/SKILL.md +0 -274
- package/skills/grok-controls/agentsam.skill.json +0 -25
- package/skills/grok-design-ui/SKILL.md +0 -122
- package/skills/grok-design-ui/agentsam.skill.json +0 -25
- package/skills/grok-design-ui/references/animations.md +0 -379
- package/skills/grok-design-ui/references/performance.md +0 -88
- package/skills/grok-design-ui/references/refined-ui.md +0 -384
- package/skills/grok-design-ui/references/surfaces.md +0 -247
- package/skills/grok-design-ui/references/typography.md +0 -123
- package/skills/grok-game-animation-frames/SKILL.md +0 -84
- package/skills/grok-game-animation-frames/agentsam.skill.json +0 -25
- package/skills/grok-game-asset-core/SKILL.md +0 -69
- package/skills/grok-game-asset-core/agentsam.skill.json +0 -25
- package/skills/grok-game-character-consistency/SKILL.md +0 -69
- package/skills/grok-game-character-consistency/agentsam.skill.json +0 -25
- package/skills/grok-game-tilesets/SKILL.md +0 -65
- package/skills/grok-game-tilesets/agentsam.skill.json +0 -25
- package/skills/grok-game-ui-icons/SKILL.md +0 -56
- package/skills/grok-game-ui-icons/agentsam.skill.json +0 -25
- package/skills/grok-generate2dmap/LICENSE +0 -21
- package/skills/grok-generate2dmap/SKILL.md +0 -120
- package/skills/grok-generate2dmap/SOURCE.md +0 -6
- package/skills/grok-generate2dmap/agentsam.skill.json +0 -25
- package/skills/grok-generate2dmap/references/deliverables.md +0 -101
- package/skills/grok-generate2dmap/references/layered-map-contract.md +0 -209
- package/skills/grok-generate2dmap/references/map-strategies.md +0 -341
- package/skills/grok-generate2dmap/references/object-production-gate.md +0 -24
- package/skills/grok-generate2dmap/references/pipeline.md +0 -149
- package/skills/grok-generate2dmap/references/prop-pack-contract.md +0 -174
- package/skills/grok-generate2dmap/references/side-scroll-stages.md +0 -29
- package/skills/grok-generate2dmap/scripts/compose_layered_preview.py +0 -157
- package/skills/grok-generate2dmap/scripts/extract_prop_pack.py +0 -369
- package/skills/grok-generate2dsprite/LICENSE +0 -21
- package/skills/grok-generate2dsprite/SKILL.md +0 -313
- package/skills/grok-generate2dsprite/SOURCE.md +0 -6
- package/skills/grok-generate2dsprite/agentsam.skill.json +0 -25
- package/skills/grok-generate2dsprite/references/modes.md +0 -124
- package/skills/grok-generate2dsprite/references/prompt-rules.md +0 -315
- package/skills/grok-generate2dsprite/scripts/generate2dsprite.py +0 -1031
- package/skills/grok-generate2dsprite/scripts/make_layout_guide.py +0 -109
- package/skills/grok-imagine/SKILL.md +0 -201
- package/skills/grok-imagine/agentsam.skill.json +0 -25
- package/skills/grok-multiplayer-p2p/SKILL.md +0 -111
- package/skills/grok-multiplayer-p2p/agentsam.skill.json +0 -25
- package/skills/grok-multiplayer-p2p/references/react-binding.md +0 -144
- package/skills/grok-multiplayer-p2p/references/signaling-relay.md +0 -269
- package/skills/grok-neon/SKILL.md +0 -157
- package/skills/grok-neon/agentsam.skill.json +0 -25
- package/skills/grok-og/SKILL.md +0 -102
- package/skills/grok-og/agentsam.skill.json +0 -25
- package/skills/grok-og/references/brand-pass.md +0 -53
- package/skills/grok-og/references/custom-card.md +0 -107
- package/skills/grok-og/references/favicon-and-icons.md +0 -48
- package/skills/grok-og/references/og-type-contract.md +0 -18
- package/skills/grok-og/references/placeholder-card.md +0 -21
- package/skills/grok-og/references/x-banner.md +0 -41
- package/skills/grok-threejs/SKILL.md +0 -67
- package/skills/grok-threejs/agentsam.skill.json +0 -25
- package/skills/grok-threejs/references/llms-full.txt +0 -2780
- package/skills/grok-video2dsprite/LICENSE +0 -21
- package/skills/grok-video2dsprite/SKILL.md +0 -236
- package/skills/grok-video2dsprite/SOURCE.md +0 -6
- package/skills/grok-video2dsprite/agentsam.skill.json +0 -25
- package/skills/grok-video2dsprite/references/pipeline.md +0 -90
- package/skills/grok-video2dsprite/references/prompt-rules.md +0 -63
- package/skills/grok-video2dsprite/scripts/video2dsprite.py +0 -490
- package/skills/grok-xai-api/SKILL.md +0 -152
- package/skills/grok-xai-api/agentsam.skill.json +0 -25
- package/test/account-session.test.mjs +0 -101
- package/test/agent-capabilities.test.mjs +0 -67
- package/test/app-authority-context.test.mjs +0 -32
- package/test/app-building-skills.test.mjs +0 -61
- package/test/apps-scaffold-contract.test.mjs +0 -115
- package/test/blender-cad.test.mjs +0 -146
- package/test/cad-docker.test.mjs +0 -96
- package/test/capabilities.test.mjs +0 -133
- package/test/cli/api-key-env-whoami.test.mjs +0 -129
- package/test/cli/catalog-authority.test.mjs +0 -64
- package/test/cli/codebaseindex-plan-ux.test.mjs +0 -37
- package/test/cli/eval-live.test.mjs +0 -219
- package/test/cli/go.test.mjs +0 -128
- package/test/cli/local-vault-and-provider-setup.test.mjs +0 -268
- package/test/cli/machine-command.test.mjs +0 -34
- package/test/cli/mcp-client.test.mjs +0 -256
- package/test/cli/preferences-runtime.test.mjs +0 -11
- package/test/cli/runtime-persist.test.mjs +0 -56
- package/test/cli/runtime-ui.test.mjs +0 -141
- package/test/cli/rust-command.test.mjs +0 -21
- package/test/cli/skill-npm-and-env.test.mjs +0 -52
- package/test/cli/status-actions.test.mjs +0 -88
- package/test/cli/wireframes-go-registry.test.mjs +0 -139
- package/test/cli-preferences.test.mjs +0 -46
- package/test/cloudflare-connector.test.mjs +0 -93
- package/test/cloudflare-runtime.test.mjs +0 -82
- package/test/context.test.mjs +0 -159
- package/test/credentials-audit.test.mjs +0 -113
- package/test/deploy-health-scan.test.mjs +0 -95
- package/test/deploy-receipt.test.mjs +0 -91
- package/test/dockerize.test.mjs +0 -93
- package/test/error-diagnostics.test.mjs +0 -124
- package/test/eval-context.test.mjs +0 -37
- package/test/execution-approvals.test.mjs +0 -27
- package/test/fixtures/cad/courtyard-house.json +0 -208
- package/test/fixtures/knowledge-rpc-worker.mjs +0 -16
- package/test/fixtures/project-authority/customer-app/.agentsam/app.json +0 -5
- package/test/fixtures/project-authority/customer-app/apps/my-product/index.ts +0 -1
- package/test/fixtures/project-authority/customer-app/wrangler.toml +0 -17
- package/test/gcloud-auth.test.mjs +0 -111
- package/test/go/build-source-identity.test.mjs +0 -31
- package/test/go/cloudflare-probe.test.mjs +0 -317
- package/test/go/distribution.test.mjs +0 -28
- package/test/google-cloud-connection.test.mjs +0 -83
- package/test/google-cloud-inventory.test.mjs +0 -64
- package/test/indexing-provider.test.mjs +0 -29
- package/test/init-options.test.mjs +0 -35
- package/test/integration/ai-access-onboarding.test.mjs +0 -47
- package/test/integration/app-command.test.mjs +0 -85
- package/test/integration/autorag-project-authority.integration.test.mjs +0 -51
- package/test/integration/autorag-runtime-discovery.test.mjs +0 -107
- package/test/integration/cad-discovery.test.mjs +0 -158
- package/test/integration/cad-docker-executor.test.mjs +0 -249
- package/test/integration/cad-execution.test.mjs +0 -184
- package/test/integration/cad-project-app.test.mjs +0 -31
- package/test/integration/cad-project-d1.test.mjs +0 -25
- package/test/integration/cad-project-native.test.mjs +0 -24
- package/test/integration/cad-project-workflow.test.mjs +0 -9
- package/test/integration/cad-project.test.mjs +0 -85
- package/test/integration/cli-help.test.mjs +0 -41
- package/test/integration/cms-app-scaffold.test.mjs +0 -77
- package/test/integration/cms-site-tenancy-contract.test.mjs +0 -268
- package/test/integration/codebaseindex-ingest.test.mjs +0 -255
- package/test/integration/core-client.integration.test.mjs +0 -55
- package/test/integration/database-hosted-honesty.test.mjs +0 -49
- package/test/integration/desktop-keychain-boundary.test.mjs +0 -45
- package/test/integration/error-runtime-rpc.test.mjs +0 -71
- package/test/integration/features-resolve.test.mjs +0 -147
- package/test/integration/hosted-work-host-authority.test.mjs +0 -47
- package/test/integration/icon-registry.test.mjs +0 -67
- package/test/integration/ingest-discover-models.test.mjs +0 -30
- package/test/integration/inspect-path-cli.test.mjs +0 -46
- package/test/integration/install-script.test.mjs +0 -110
- package/test/integration/inventory-core.test.mjs +0 -53
- package/test/integration/inventory-eligibility.test.mjs +0 -59
- package/test/integration/inventory-evidence.test.mjs +0 -125
- package/test/integration/knowledge-rpc.test.mjs +0 -112
- package/test/integration/local-fs.test.mjs +0 -113
- package/test/integration/local-provider-bridge.test.mjs +0 -65
- package/test/integration/local-studio-settings-production.test.mjs +0 -40
- package/test/integration/lockfile-sync.test.mjs +0 -26
- package/test/integration/merkle-cli.test.mjs +0 -61
- package/test/integration/merkle-persistence-identity.test.mjs +0 -48
- package/test/integration/plugins-cloudflare.integration.test.mjs +0 -28
- package/test/integration/provider-env-cli.test.mjs +0 -60
- package/test/integration/provider-factory.test.mjs +0 -197
- package/test/integration/repository-company-graph.test.mjs +0 -90
- package/test/integration/runtime-migrations.test.mjs +0 -87
- package/test/integration/runtime-status.integration.test.mjs +0 -227
- package/test/integration/sam-activity-recovery.test.mjs +0 -147
- package/test/integration/sam-decision.test.mjs +0 -584
- package/test/integration/sam-kernel.test.mjs +0 -99
- package/test/integration/sam-planning-astar.test.mjs +0 -279
- package/test/integration/scaffold-cloudflare.test.mjs +0 -46
- package/test/integration/skill-runtime.test.mjs +0 -240
- package/test/integration/storage-architecture.test.mjs +0 -154
- package/test/integration/store-discovery.test.mjs +0 -44
- package/test/integration/studio-fs-pty-e2e.test.mjs +0 -294
- package/test/integration/terminal-exec.integration.test.mjs +0 -86
- package/test/integration/theme-package-registry.test.mjs +0 -31
- package/test/integration/tool-runtime.test.mjs +0 -124
- package/test/integration/tool-schema.test.mjs +0 -59
- package/test/jr-dev-skill.test.mjs +0 -26
- package/test/knowledge-context-pack.test.mjs +0 -19
- package/test/knowledge-postgres.test.mjs +0 -40
- package/test/knowledge-service.test.mjs +0 -110
- package/test/knowledge.test.mjs +0 -206
- package/test/live/terminal-transport.live.test.mjs +0 -24
- package/test/local-sessions.test.mjs +0 -57
- package/test/local-studio-deploy.test.mjs +0 -83
- package/test/loopback-oauth.test.mjs +0 -53
- package/test/merkle-render.test.mjs +0 -31
- package/test/mini.test.mjs +0 -140
- package/test/model-catalog.test.mjs +0 -70
- package/test/models.test.mjs +0 -309
- package/test/npm10-lock.test.mjs +0 -29
- package/test/ollama.test.mjs +0 -137
- package/test/open-url.test.mjs +0 -64
- package/test/openai-responses.test.mjs +0 -155
- package/test/portable-context.test.mjs +0 -94
- package/test/project-config.test.mjs +0 -81
- package/test/project-rules.test.mjs +0 -44
- package/test/provider-credentials.test.mjs +0 -106
- package/test/rehydrate.test.mjs +0 -25
- package/test/release-hygiene.test.mjs +0 -42
- package/test/repository-snapshot-view.test.mjs +0 -112
- package/test/responses-runner.test.mjs +0 -465
- package/test/runtime-activity.test.mjs +0 -98
- package/test/sdk-worker-contract.test.mjs +0 -72
- package/test/security.test.mjs +0 -266
- package/test/setup-planner.test.mjs +0 -74
- package/test/setup-runtime.test.mjs +0 -51
- package/test/shell.test.mjs +0 -281
- package/test/skills.test.mjs +0 -22
- package/test/smoke.mjs +0 -122
- package/test/telemetry.test.mjs +0 -79
- package/test/terminal/local-pty.mock.test.mjs +0 -153
- package/test/terminal-machine-identity.test.mjs +0 -88
- package/test/theme-portability.test.mjs +0 -14
- package/test/tools-search.test.mjs +0 -73
- package/test/unit/website-assets-bindings.test.mjs +0 -60
- package/test/whoami-resume.test.mjs +0 -157
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
import {
|
|
2
|
+
GOAP_SCHEMAS,
|
|
3
|
+
normalizeActionSpec,
|
|
4
|
+
normalizeBlackboard,
|
|
5
|
+
normalizeGoal,
|
|
6
|
+
} from './contracts.js';
|
|
7
|
+
import { goapInputError } from './errors.js';
|
|
8
|
+
|
|
9
|
+
const TODO_TO_GOAL_STATUS = Object.freeze({
|
|
10
|
+
open: 'proposed',
|
|
11
|
+
running: 'active',
|
|
12
|
+
blocked: 'blocked',
|
|
13
|
+
complete: 'satisfied',
|
|
14
|
+
cancelled: 'cancelled',
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
const PRIORITY_COST = Object.freeze({
|
|
18
|
+
critical: 1,
|
|
19
|
+
high: 2,
|
|
20
|
+
medium: 3,
|
|
21
|
+
low: 4,
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
function clean(value) {
|
|
25
|
+
return value == null ? '' : String(value).trim();
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function array(value) {
|
|
29
|
+
return Array.isArray(value) ? value : [];
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function object(value) {
|
|
33
|
+
return value && typeof value === 'object' && !Array.isArray(value) ? value : {};
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function taskById(plan) {
|
|
37
|
+
return new Map(array(plan?.tasks).map((task) => [task.id, task]));
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function blockersFor(plan, task) {
|
|
41
|
+
const byId = taskById(plan);
|
|
42
|
+
return array(task?.metadata?.depends_on)
|
|
43
|
+
.map((id) => byId.get(id) || { id, title: null, status: 'missing' })
|
|
44
|
+
.filter((dependency) => dependency.status !== 'complete')
|
|
45
|
+
.map((dependency) => ({
|
|
46
|
+
id: dependency.id,
|
|
47
|
+
title: dependency.title || null,
|
|
48
|
+
status: dependency.status,
|
|
49
|
+
}));
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export function projectPlanActions(plan = {}) {
|
|
53
|
+
const available = [];
|
|
54
|
+
const blocked = [];
|
|
55
|
+
|
|
56
|
+
for (const task of array(plan.tasks)) {
|
|
57
|
+
if (task.status !== 'open') continue;
|
|
58
|
+
const blockers = blockersFor(plan, task);
|
|
59
|
+
const action = {
|
|
60
|
+
id: task.id,
|
|
61
|
+
title: task.title,
|
|
62
|
+
status: task.status,
|
|
63
|
+
spec: normalizeActionSpec({
|
|
64
|
+
preconditions: array(task.metadata?.depends_on).map((todoId) => ({
|
|
65
|
+
fact: 'todo.complete',
|
|
66
|
+
todo_id: todoId,
|
|
67
|
+
value: true,
|
|
68
|
+
})),
|
|
69
|
+
effects: [{
|
|
70
|
+
fact: 'todo.complete',
|
|
71
|
+
todo_id: task.id,
|
|
72
|
+
value: true,
|
|
73
|
+
}],
|
|
74
|
+
cost: PRIORITY_COST[task.priority] ?? 3,
|
|
75
|
+
metadata: {
|
|
76
|
+
kind: task.metadata?.kind || 'work',
|
|
77
|
+
priority: task.priority || 'medium',
|
|
78
|
+
sort_order: Number(task.sort_order ?? 50),
|
|
79
|
+
},
|
|
80
|
+
}),
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
if (blockers.length) blocked.push({ ...action, blockers });
|
|
84
|
+
else available.push(action);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
return { available, blocked };
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
export function projectGoapWorld({
|
|
91
|
+
repository = {},
|
|
92
|
+
plan,
|
|
93
|
+
activeTodo = null,
|
|
94
|
+
actions = null,
|
|
95
|
+
knowledge = {},
|
|
96
|
+
evidence = null,
|
|
97
|
+
accountId = null,
|
|
98
|
+
revision = 1,
|
|
99
|
+
updatedAt = null,
|
|
100
|
+
} = {}) {
|
|
101
|
+
const repositoryId = clean(repository.repository_id ?? repository.repositoryId);
|
|
102
|
+
if (!repositoryId) {
|
|
103
|
+
throw goapInputError('repository.repository_id is required for GOAP world projection', {
|
|
104
|
+
stage: 'project_world',
|
|
105
|
+
details: { field: 'repository.repository_id' },
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
if (!plan?.id) {
|
|
109
|
+
throw goapInputError('plan.id is required for GOAP world projection', {
|
|
110
|
+
stage: 'project_world',
|
|
111
|
+
details: { field: 'plan.id' },
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
const projectedActions = actions || projectPlanActions(plan);
|
|
116
|
+
const todo = activeTodo || null;
|
|
117
|
+
const goalId = todo?.id || plan.id;
|
|
118
|
+
const goalTitle = todo?.title || plan.title || plan.id;
|
|
119
|
+
const goalStatus = todo
|
|
120
|
+
? (TODO_TO_GOAL_STATUS[todo.status] || 'proposed')
|
|
121
|
+
: (Number(plan.tasks_done || 0) === Number(plan.tasks_total || -1) ? 'satisfied' : 'active');
|
|
122
|
+
|
|
123
|
+
const state = {
|
|
124
|
+
plan: {
|
|
125
|
+
id: plan.id,
|
|
126
|
+
title: plan.title || null,
|
|
127
|
+
status: plan.status || null,
|
|
128
|
+
tasks_done: Number(plan.tasks_done || 0),
|
|
129
|
+
tasks_total: Number(plan.tasks_total || array(plan.tasks).length),
|
|
130
|
+
},
|
|
131
|
+
todo: todo ? {
|
|
132
|
+
id: todo.id,
|
|
133
|
+
title: todo.title || null,
|
|
134
|
+
status: todo.status || null,
|
|
135
|
+
priority: todo.priority || null,
|
|
136
|
+
kind: todo.metadata?.kind || 'work',
|
|
137
|
+
depends_on: array(todo.metadata?.depends_on),
|
|
138
|
+
acceptance: array(todo.metadata?.acceptance),
|
|
139
|
+
evidence: array(todo.metadata?.evidence),
|
|
140
|
+
} : null,
|
|
141
|
+
repository: {
|
|
142
|
+
repository_id: repositoryId,
|
|
143
|
+
branch: repository.branch || null,
|
|
144
|
+
revision_sha: repository.revision_sha || repository.revisionSha || null,
|
|
145
|
+
dirty: repository.dirty ?? null,
|
|
146
|
+
merkle_root: repository.merkle_root || null,
|
|
147
|
+
},
|
|
148
|
+
knowledge: { ...object(knowledge) },
|
|
149
|
+
actions: projectedActions,
|
|
150
|
+
evidence: evidence || null,
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
const blackboard = normalizeBlackboard({
|
|
154
|
+
id: 'world:' + repositoryId,
|
|
155
|
+
account_id: clean(accountId) || null,
|
|
156
|
+
repository_id: repositoryId,
|
|
157
|
+
current_goal_id: goalId,
|
|
158
|
+
state,
|
|
159
|
+
revision,
|
|
160
|
+
locked_by: 'project_local_plan',
|
|
161
|
+
checkpoint_sha: repository.revision_sha || repository.revisionSha || null,
|
|
162
|
+
last_action: 'world_snapshot_projected',
|
|
163
|
+
updated_at: updatedAt,
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
const goal = normalizeGoal({
|
|
167
|
+
id: goalId,
|
|
168
|
+
account_id: clean(accountId),
|
|
169
|
+
repository_id: repositoryId,
|
|
170
|
+
title: goalTitle,
|
|
171
|
+
goal_status: goalStatus,
|
|
172
|
+
priority: todo?.priority || null,
|
|
173
|
+
spec: {
|
|
174
|
+
desired: [{
|
|
175
|
+
fact: todo ? 'todo.complete' : 'plan.complete',
|
|
176
|
+
[todo ? 'todo_id' : 'plan_id']: goalId,
|
|
177
|
+
value: true,
|
|
178
|
+
}],
|
|
179
|
+
constraints: array(todo?.metadata?.depends_on).map((todoId) => ({
|
|
180
|
+
fact: 'todo.complete',
|
|
181
|
+
todo_id: todoId,
|
|
182
|
+
value: true,
|
|
183
|
+
})),
|
|
184
|
+
metadata: {
|
|
185
|
+
source: 'project_local_plan',
|
|
186
|
+
plan_id: plan.id,
|
|
187
|
+
todo_id: todo?.id || null,
|
|
188
|
+
},
|
|
189
|
+
},
|
|
190
|
+
updated_at: updatedAt,
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
return {
|
|
194
|
+
schema: GOAP_SCHEMAS.world,
|
|
195
|
+
source: 'project_local_plan',
|
|
196
|
+
repository_id: repositoryId,
|
|
197
|
+
blackboard,
|
|
198
|
+
goal,
|
|
199
|
+
actions: projectedActions,
|
|
200
|
+
evidence: evidence || null,
|
|
201
|
+
};
|
|
202
|
+
}
|
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
import assert from 'node:assert/strict';
|
|
2
|
+
import test from 'node:test';
|
|
3
|
+
import { DatabaseSync } from 'node:sqlite';
|
|
4
|
+
import {
|
|
5
|
+
AgentSamError,
|
|
6
|
+
ERROR_REASON,
|
|
7
|
+
planRecovery,
|
|
8
|
+
} from '@inneranimalmedia/agentsam-errors';
|
|
9
|
+
import {
|
|
10
|
+
GOAP_SCHEMAS,
|
|
11
|
+
MemoryGoapAdapter,
|
|
12
|
+
createD1SqliteGoapAdapter,
|
|
13
|
+
createGoapControlPlane,
|
|
14
|
+
goalStatusFromTicket,
|
|
15
|
+
ticketStatusFromGoal,
|
|
16
|
+
} from '../src/index.js';
|
|
17
|
+
|
|
18
|
+
const scope = {
|
|
19
|
+
account_id: 'acct_test',
|
|
20
|
+
repository_id: 'github:example/repo',
|
|
21
|
+
workspace_id: 'ws_test',
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
test('status mapping preserves database statuses while exposing logical GOAP states', () => {
|
|
25
|
+
assert.equal(goalStatusFromTicket('backlog'), 'proposed');
|
|
26
|
+
assert.equal(goalStatusFromTicket('in_review'), 'verifying');
|
|
27
|
+
assert.equal(ticketStatusFromGoal('satisfied'), 'shipped');
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
test('memory adapter atomically activates goal with CAS and append-only cursor', async () => {
|
|
31
|
+
const adapter = new MemoryGoapAdapter({
|
|
32
|
+
blackboards: [{
|
|
33
|
+
...scope,
|
|
34
|
+
id: 'bb_1',
|
|
35
|
+
current_goal_id: null,
|
|
36
|
+
state: { build: { valid: false } },
|
|
37
|
+
revision: 4,
|
|
38
|
+
}],
|
|
39
|
+
goals: [{
|
|
40
|
+
...scope,
|
|
41
|
+
id: 'tkt_1',
|
|
42
|
+
title: 'Make build valid',
|
|
43
|
+
status: 'backlog',
|
|
44
|
+
goal_spec_json: { desired: [{ fact: 'build.valid', op: 'eq', value: true }] },
|
|
45
|
+
}],
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
const service = createGoapControlPlane({ ports: adapter.ports(), clock: () => 100 });
|
|
49
|
+
const activated = await service.activateGoal({
|
|
50
|
+
scope,
|
|
51
|
+
goalId: 'tkt_1',
|
|
52
|
+
expectedRevision: 4,
|
|
53
|
+
actor: { type: 'test', id: 'runner' },
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
assert.equal(activated.blackboard.revision, 5);
|
|
57
|
+
assert.equal(activated.blackboard.current_goal_id, 'tkt_1');
|
|
58
|
+
assert.equal(activated.goal.status, 'active');
|
|
59
|
+
assert.equal(activated.events.length, 1);
|
|
60
|
+
assert.equal(activated.events[0].type, 'goal.activated');
|
|
61
|
+
assert.equal(activated.events[0].payload.blackboard_revision, 5);
|
|
62
|
+
assert.match(activated.events[0].cursor, /^memory:/);
|
|
63
|
+
|
|
64
|
+
await assert.rejects(
|
|
65
|
+
service.activateGoal({ scope, goalId: 'tkt_1', expectedRevision: 4 }),
|
|
66
|
+
(error) => {
|
|
67
|
+
assert.equal(error instanceof AgentSamError, true);
|
|
68
|
+
assert.equal(error.reason, ERROR_REASON.STALE_VERSION);
|
|
69
|
+
assert.equal(error.code, 'ABORTED');
|
|
70
|
+
assert.equal(error.envelope.tool, 'goap');
|
|
71
|
+
assert.equal(planRecovery(error.envelope).disposition, 'retry');
|
|
72
|
+
return true;
|
|
73
|
+
},
|
|
74
|
+
);
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
function d1Like(db) {
|
|
78
|
+
return {
|
|
79
|
+
prepare(sql) {
|
|
80
|
+
const statement = db.prepare(sql);
|
|
81
|
+
return {
|
|
82
|
+
bind(...values) {
|
|
83
|
+
return {
|
|
84
|
+
async first() {
|
|
85
|
+
return statement.get(...values) ?? null;
|
|
86
|
+
},
|
|
87
|
+
async all() {
|
|
88
|
+
return { results: statement.all(...values) };
|
|
89
|
+
},
|
|
90
|
+
async run() {
|
|
91
|
+
return statement.run(...values);
|
|
92
|
+
},
|
|
93
|
+
};
|
|
94
|
+
},
|
|
95
|
+
};
|
|
96
|
+
},
|
|
97
|
+
async batch(statements) {
|
|
98
|
+
db.exec('BEGIN IMMEDIATE');
|
|
99
|
+
try {
|
|
100
|
+
const results = [];
|
|
101
|
+
for (const statement of statements) results.push(await statement.run());
|
|
102
|
+
db.exec('COMMIT');
|
|
103
|
+
return results;
|
|
104
|
+
} catch (error) {
|
|
105
|
+
try { db.exec('ROLLBACK'); } catch {}
|
|
106
|
+
throw error;
|
|
107
|
+
}
|
|
108
|
+
},
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
function createSqlite({ eventOwnership = true } = {}) {
|
|
113
|
+
const sqlite = new DatabaseSync(':memory:');
|
|
114
|
+
const eventOwnershipColumns = eventOwnership ? 'account_id TEXT, repository_id TEXT,' : '';
|
|
115
|
+
sqlite.exec([
|
|
116
|
+
'CREATE TABLE agentsam_workspace_state (',
|
|
117
|
+
'id TEXT PRIMARY KEY, workspace_id TEXT NOT NULL, repository_id TEXT NOT NULL,',
|
|
118
|
+
'current_task_id TEXT, state_json TEXT NOT NULL DEFAULT \'{}\',',
|
|
119
|
+
'state_schema TEXT NOT NULL DEFAULT \'agentsam.blackboard.v1\',',
|
|
120
|
+
'revision INTEGER NOT NULL DEFAULT 1, locked_by TEXT, lock_expires_at INTEGER,',
|
|
121
|
+
'checkpoint_sha TEXT, last_agent_action TEXT, updated_at INTEGER NOT NULL);',
|
|
122
|
+
'CREATE TABLE agentsam_tickets (',
|
|
123
|
+
'id TEXT PRIMARY KEY, title TEXT NOT NULL, status TEXT NOT NULL, priority TEXT,',
|
|
124
|
+
'account_id TEXT NOT NULL, repository_id TEXT NOT NULL, goal_schema TEXT,',
|
|
125
|
+
'goal_spec_json TEXT, created_at INTEGER NOT NULL, updated_at INTEGER NOT NULL);',
|
|
126
|
+
'CREATE TABLE agentsam_ticket_events (',
|
|
127
|
+
'id TEXT PRIMARY KEY, ticket_id TEXT NOT NULL, event_type TEXT NOT NULL, detail TEXT,',
|
|
128
|
+
'created_at INTEGER NOT NULL, actor_type TEXT, actor_id TEXT, ' + eventOwnershipColumns,
|
|
129
|
+
'payload_json TEXT NOT NULL DEFAULT \'{}\', workflow_run_id TEXT, execution_step_id TEXT,',
|
|
130
|
+
'schema_version TEXT NOT NULL DEFAULT \'agentsam.event.v1\');',
|
|
131
|
+
].join('\n'));
|
|
132
|
+
sqlite.prepare(
|
|
133
|
+
'INSERT INTO agentsam_workspace_state ' +
|
|
134
|
+
'(id, workspace_id, repository_id, current_task_id, state_json, revision, updated_at) ' +
|
|
135
|
+
'VALUES (?, ?, ?, NULL, \'{}\', 7, 1)',
|
|
136
|
+
).run('bb_sql', scope.workspace_id, scope.repository_id);
|
|
137
|
+
sqlite.prepare(
|
|
138
|
+
'INSERT INTO agentsam_tickets ' +
|
|
139
|
+
'(id, title, status, account_id, repository_id, goal_schema, goal_spec_json, created_at, updated_at) ' +
|
|
140
|
+
'VALUES (?, ?, \'backlog\', ?, ?, ?, ?, 1, 1)',
|
|
141
|
+
).run(
|
|
142
|
+
'tkt_sql',
|
|
143
|
+
'Ship portable GOAP',
|
|
144
|
+
scope.account_id,
|
|
145
|
+
scope.repository_id,
|
|
146
|
+
GOAP_SCHEMAS.goal,
|
|
147
|
+
JSON.stringify({ schema: GOAP_SCHEMAS.goal, desired: [] }),
|
|
148
|
+
);
|
|
149
|
+
return sqlite;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
test('repository_join blackboard ownership rejects cross-account reads on shared stores', async () => {
|
|
154
|
+
const sqlite = createSqlite();
|
|
155
|
+
sqlite.exec(
|
|
156
|
+
'CREATE TABLE code_repositories (id TEXT PRIMARY KEY, account_id TEXT NOT NULL);',
|
|
157
|
+
);
|
|
158
|
+
sqlite.prepare(
|
|
159
|
+
'INSERT INTO code_repositories (id, account_id) VALUES (?, ?)',
|
|
160
|
+
).run(scope.repository_id, scope.account_id);
|
|
161
|
+
|
|
162
|
+
const ports = createD1SqliteGoapAdapter({
|
|
163
|
+
db: d1Like(sqlite),
|
|
164
|
+
blackboardOwnership: 'repository_join',
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
const owned = await ports.blackboardStore.get(scope);
|
|
168
|
+
assert.equal(owned.repository_id, scope.repository_id);
|
|
169
|
+
|
|
170
|
+
const foreign = await ports.blackboardStore.get({
|
|
171
|
+
...scope,
|
|
172
|
+
account_id: 'acct_other',
|
|
173
|
+
});
|
|
174
|
+
assert.equal(foreign, null);
|
|
175
|
+
|
|
176
|
+
sqlite.close();
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
test('D1/SQLite adapter atomically guards stale revisions with canonical AgentSam errors', async () => {
|
|
180
|
+
const sqlite = createSqlite();
|
|
181
|
+
const ports = createD1SqliteGoapAdapter({ db: d1Like(sqlite) });
|
|
182
|
+
const service = createGoapControlPlane({ ports, clock: () => 1234 });
|
|
183
|
+
|
|
184
|
+
await assert.rejects(
|
|
185
|
+
service.activateGoal({ scope, goalId: 'tkt_sql', expectedRevision: 6 }),
|
|
186
|
+
(error) => {
|
|
187
|
+
assert.equal(error instanceof AgentSamError, true);
|
|
188
|
+
assert.equal(error.reason, ERROR_REASON.STALE_VERSION);
|
|
189
|
+
assert.equal(error.envelope.domain, 'tool');
|
|
190
|
+
assert.equal(error.envelope.tool, 'goap');
|
|
191
|
+
return true;
|
|
192
|
+
},
|
|
193
|
+
);
|
|
194
|
+
|
|
195
|
+
assert.equal(sqlite.prepare('SELECT revision FROM agentsam_workspace_state').get().revision, 7);
|
|
196
|
+
assert.equal(sqlite.prepare('SELECT status FROM agentsam_tickets').get().status, 'backlog');
|
|
197
|
+
assert.equal(sqlite.prepare('SELECT COUNT(*) AS n FROM agentsam_ticket_events').get().n, 0);
|
|
198
|
+
|
|
199
|
+
const result = await service.activateGoal({
|
|
200
|
+
scope,
|
|
201
|
+
goalId: 'tkt_sql',
|
|
202
|
+
expectedRevision: 7,
|
|
203
|
+
actor: { type: 'test', id: 'sqlite' },
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
assert.equal(result.blackboard.revision, 8);
|
|
207
|
+
assert.equal(result.blackboard.current_goal_id, 'tkt_sql');
|
|
208
|
+
assert.equal(result.goal.status, 'active');
|
|
209
|
+
assert.equal(result.events[0].type, 'goal.activated');
|
|
210
|
+
assert.match(result.events[0].cursor, /^sqlite:/);
|
|
211
|
+
|
|
212
|
+
const eventRow = sqlite.prepare(
|
|
213
|
+
'SELECT account_id, repository_id, payload_json, schema_version FROM agentsam_ticket_events LIMIT 1',
|
|
214
|
+
).get();
|
|
215
|
+
assert.equal(eventRow.account_id, scope.account_id);
|
|
216
|
+
assert.equal(eventRow.repository_id, scope.repository_id);
|
|
217
|
+
assert.equal(eventRow.schema_version, GOAP_SCHEMAS.event);
|
|
218
|
+
assert.equal(JSON.parse(eventRow.payload_json).blackboard_revision, 8);
|
|
219
|
+
|
|
220
|
+
sqlite.close();
|
|
221
|
+
});
|
|
222
|
+
|
|
223
|
+
test('ticket_join event ownership supports the legacy platform event table', async () => {
|
|
224
|
+
const sqlite = createSqlite({ eventOwnership: false });
|
|
225
|
+
const ports = createD1SqliteGoapAdapter({
|
|
226
|
+
db: d1Like(sqlite),
|
|
227
|
+
eventOwnership: 'ticket_join',
|
|
228
|
+
cursorPrefix: 'd1',
|
|
229
|
+
});
|
|
230
|
+
const service = createGoapControlPlane({ ports, clock: () => 2000 });
|
|
231
|
+
|
|
232
|
+
const result = await service.activateGoal({
|
|
233
|
+
scope,
|
|
234
|
+
goalId: 'tkt_sql',
|
|
235
|
+
expectedRevision: 7,
|
|
236
|
+
});
|
|
237
|
+
|
|
238
|
+
assert.equal(result.blackboard.revision, 8);
|
|
239
|
+
assert.equal(result.goal.status, 'active');
|
|
240
|
+
assert.equal(result.events.length, 1);
|
|
241
|
+
assert.match(result.events[0].cursor, /^d1:/);
|
|
242
|
+
assert.equal(sqlite.prepare('SELECT COUNT(*) AS n FROM agentsam_ticket_events').get().n, 1);
|
|
243
|
+
|
|
244
|
+
sqlite.close();
|
|
245
|
+
});
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import assert from 'node:assert/strict';
|
|
2
|
+
import test from 'node:test';
|
|
3
|
+
import { projectGoapWorld, projectPlanActions } from '../src/world.js';
|
|
4
|
+
|
|
5
|
+
const plan = {
|
|
6
|
+
id: 'plan_1',
|
|
7
|
+
title: 'Ship portable loop',
|
|
8
|
+
status: 'active',
|
|
9
|
+
tasks_done: 1,
|
|
10
|
+
tasks_total: 3,
|
|
11
|
+
tasks: [
|
|
12
|
+
{
|
|
13
|
+
id: 'todo_done',
|
|
14
|
+
title: 'Freeze contract',
|
|
15
|
+
status: 'complete',
|
|
16
|
+
priority: 'high',
|
|
17
|
+
sort_order: 10,
|
|
18
|
+
metadata: { kind: 'decision', depends_on: [] },
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
id: 'todo_active',
|
|
22
|
+
title: 'Project world',
|
|
23
|
+
status: 'running',
|
|
24
|
+
priority: 'critical',
|
|
25
|
+
sort_order: 20,
|
|
26
|
+
metadata: { kind: 'implement', depends_on: ['todo_done'], acceptance: [], evidence: [] },
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
id: 'todo_next',
|
|
30
|
+
title: 'Verify loop',
|
|
31
|
+
status: 'open',
|
|
32
|
+
priority: 'high',
|
|
33
|
+
sort_order: 30,
|
|
34
|
+
metadata: { kind: 'verify', depends_on: ['todo_active'] },
|
|
35
|
+
},
|
|
36
|
+
],
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
test('projectPlanActions converts TODO dependencies into GOAP preconditions', () => {
|
|
40
|
+
const actions = projectPlanActions(plan);
|
|
41
|
+
assert.equal(actions.available.length, 0);
|
|
42
|
+
assert.equal(actions.blocked.length, 1);
|
|
43
|
+
assert.equal(actions.blocked[0].id, 'todo_next');
|
|
44
|
+
assert.equal(actions.blocked[0].blockers[0].id, 'todo_active');
|
|
45
|
+
assert.deepEqual(actions.blocked[0].spec.preconditions[0], {
|
|
46
|
+
fact: 'todo.complete',
|
|
47
|
+
todo_id: 'todo_active',
|
|
48
|
+
value: true,
|
|
49
|
+
});
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
test('projectGoapWorld emits canonical world, blackboard, goal, and action contracts', () => {
|
|
53
|
+
const world = projectGoapWorld({
|
|
54
|
+
repository: {
|
|
55
|
+
repository_id: 'github:example/repo',
|
|
56
|
+
branch: 'main',
|
|
57
|
+
revision_sha: 'abc123',
|
|
58
|
+
dirty: false,
|
|
59
|
+
merkle_root: 'sha256:merkle',
|
|
60
|
+
},
|
|
61
|
+
plan,
|
|
62
|
+
activeTodo: plan.tasks[1],
|
|
63
|
+
knowledge: { status: 'current', generation_id: 'gen_1' },
|
|
64
|
+
evidence: { primitive: 'repository.audit', chars: 900 },
|
|
65
|
+
revision: 7,
|
|
66
|
+
updatedAt: 123,
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
assert.equal(world.schema, 'agentsam.goap.world.v1');
|
|
70
|
+
assert.equal(world.blackboard.schema, 'agentsam.blackboard.v1');
|
|
71
|
+
assert.equal(world.blackboard.current_goal_id, 'todo_active');
|
|
72
|
+
assert.equal(world.blackboard.revision, 7);
|
|
73
|
+
assert.equal(world.blackboard.state.repository.merkle_root, 'sha256:merkle');
|
|
74
|
+
assert.equal(world.goal.schema, 'agentsam.goal.v1');
|
|
75
|
+
assert.equal(world.goal.id, 'todo_active');
|
|
76
|
+
assert.equal(world.goal.status, 'active');
|
|
77
|
+
assert.equal(world.goal.spec.desired[0].fact, 'todo.complete');
|
|
78
|
+
assert.equal(world.actions.blocked[0].id, 'todo_next');
|
|
79
|
+
});
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@inneranimalmedia/agentsam-knowledge",
|
|
3
|
-
"version": "2.6.
|
|
3
|
+
"version": "2.6.9",
|
|
4
4
|
"description": "Portable AutoRAG discovery, adapter registries, probes, and company routing contracts for AgentSam.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -25,5 +25,6 @@
|
|
|
25
25
|
},
|
|
26
26
|
"files": [
|
|
27
27
|
"src"
|
|
28
|
-
]
|
|
28
|
+
],
|
|
29
|
+
"license": "MIT"
|
|
29
30
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@inneranimalmedia/agentsam-queue-control",
|
|
3
|
-
"version": "2.6.
|
|
3
|
+
"version": "2.6.9",
|
|
4
4
|
"description": "Portable AgentSam queue, job-routing, batching, and execution-control primitives with Cloudflare-first adapters.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./src/index.js",
|
|
@@ -14,6 +14,7 @@ const COMPATIBILITY_DATE: &str = "2026-09-27";
|
|
|
14
14
|
#[derive(Parser, Debug)]
|
|
15
15
|
#[command(
|
|
16
16
|
name = "agentsam-rapid-rust",
|
|
17
|
+
bin_name = "agentsam rust",
|
|
17
18
|
version,
|
|
18
19
|
about = "Scaffold, teach, verify, build, and explicitly deploy Cloudflare Rust/Wasm Workers"
|
|
19
20
|
)]
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@inneranimalmedia/agentsam-repository",
|
|
3
|
-
"version": "2.6.
|
|
3
|
+
"version": "2.6.9",
|
|
4
4
|
"description": "Portable AgentSam repository identity, Merkle, semantic file metadata, persistence, and repository graph runtime contracts.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./src/index.js",
|
|
@@ -31,5 +31,6 @@
|
|
|
31
31
|
},
|
|
32
32
|
"files": [
|
|
33
33
|
"src"
|
|
34
|
-
]
|
|
34
|
+
],
|
|
35
|
+
"license": "MIT"
|
|
35
36
|
}
|
|
@@ -5,7 +5,6 @@ import { execFileSync } from 'node:child_process';
|
|
|
5
5
|
import { tryResolveGitContext } from './git-context.js';
|
|
6
6
|
import {
|
|
7
7
|
createTicketId,
|
|
8
|
-
createAgentRunId,
|
|
9
8
|
generateTicketCreateSql,
|
|
10
9
|
generateTicketCloseSql,
|
|
11
10
|
} from './tickets.js';
|
|
@@ -252,7 +251,6 @@ export async function createGoapGoal({
|
|
|
252
251
|
if (!accId) throw new Error('account_id_required');
|
|
253
252
|
|
|
254
253
|
const ticketId = createTicketId();
|
|
255
|
-
const agentRunId = createAgentRunId();
|
|
256
254
|
const now = Math.floor(Date.now() / 1000);
|
|
257
255
|
|
|
258
256
|
const { sql: ticketSql } = generateTicketCreateSql({
|
|
@@ -268,7 +266,6 @@ export async function createGoapGoal({
|
|
|
268
266
|
repositoryId: repoId,
|
|
269
267
|
ownerRef: repoId,
|
|
270
268
|
source: 'agentsam_sdk',
|
|
271
|
-
agentRunId,
|
|
272
269
|
now,
|
|
273
270
|
});
|
|
274
271
|
|
|
@@ -305,7 +302,7 @@ ON CONFLICT(repository_id) DO UPDATE SET
|
|
|
305
302
|
return {
|
|
306
303
|
ok: true,
|
|
307
304
|
ticketId,
|
|
308
|
-
agentRunId,
|
|
305
|
+
agentRunId: null,
|
|
309
306
|
title: cleanTitle,
|
|
310
307
|
status,
|
|
311
308
|
priority,
|
|
@@ -338,23 +335,17 @@ export async function switchGoapGoal({
|
|
|
338
335
|
query,
|
|
339
336
|
wranglerConfig,
|
|
340
337
|
databaseName,
|
|
341
|
-
sql: `SELECT id, account_id, repository_id FROM agentsam_tickets WHERE id = '${sqlEsc(tid)}' LIMIT 1;`,
|
|
338
|
+
sql: `SELECT id, account_id, repository_id, agent_run_id FROM agentsam_tickets WHERE id = '${sqlEsc(tid)}' LIMIT 1;`,
|
|
342
339
|
});
|
|
343
340
|
const ticket = lookup?.[0]?.results?.[0];
|
|
344
341
|
const accId = clean(accountId);
|
|
345
342
|
if (!ticket) throw new Error('ticket_not_found');
|
|
346
343
|
if (ticket.repository_id && ticket.repository_id !== repoId) throw new Error('ticket_repository_mismatch');
|
|
347
344
|
if (!accId || ticket.account_id !== accId) throw new Error('ticket_account_mismatch');
|
|
348
|
-
const runId = createAgentRunId();
|
|
349
345
|
|
|
350
346
|
const sql = `
|
|
351
|
-
INSERT INTO agentsam_agent_run (
|
|
352
|
-
id, account_id, mode, status, started_at_unix, created_at_unix, updated_at_unix
|
|
353
|
-
) VALUES ('${sqlEsc(runId)}', '${sqlEsc(accId)}', 'agent', 'running', ${now}, ${now}, ${now});
|
|
354
|
-
|
|
355
347
|
UPDATE agentsam_tickets SET
|
|
356
348
|
status = 'active',
|
|
357
|
-
agent_run_id = '${sqlEsc(runId)}',
|
|
358
349
|
updated_at = ${now}
|
|
359
350
|
WHERE id = '${sqlEsc(tid)}';
|
|
360
351
|
|
|
@@ -385,7 +376,7 @@ ON CONFLICT(repository_id) DO UPDATE SET
|
|
|
385
376
|
ok: true,
|
|
386
377
|
ticketId: tid,
|
|
387
378
|
repositoryId: repoId,
|
|
388
|
-
agentRunId:
|
|
379
|
+
agentRunId: ticket.agent_run_id || null,
|
|
389
380
|
};
|
|
390
381
|
}
|
|
391
382
|
|
|
@@ -420,7 +411,7 @@ export async function closeGoapGoal({
|
|
|
420
411
|
query,
|
|
421
412
|
wranglerConfig,
|
|
422
413
|
databaseName,
|
|
423
|
-
sql: `SELECT id, account_id, repository_id FROM agentsam_tickets WHERE id = '${sqlEsc(tid)}' LIMIT 1;`,
|
|
414
|
+
sql: `SELECT id, account_id, repository_id, agent_run_id FROM agentsam_tickets WHERE id = '${sqlEsc(tid)}' LIMIT 1;`,
|
|
424
415
|
});
|
|
425
416
|
const ticket = lookup?.[0]?.results?.[0];
|
|
426
417
|
const accId = clean(accountId);
|
|
@@ -471,6 +462,8 @@ export function renderGoapStatus(state = {}) {
|
|
|
471
462
|
const cp = state.cursor || {};
|
|
472
463
|
const git = state.git || {};
|
|
473
464
|
const headSha = git?.revisionSha || git?.headSha || 'unknown';
|
|
465
|
+
const localPlan = state.localPlan || null;
|
|
466
|
+
const world = state.worldSnapshot || null;
|
|
474
467
|
|
|
475
468
|
return [
|
|
476
469
|
'================================================================================',
|
|
@@ -487,6 +480,12 @@ export function renderGoapStatus(state = {}) {
|
|
|
487
480
|
`Checkpoint: ${ws.checkpoint_sha ? ws.checkpoint_sha.slice(0, 10) : 'none'} (Tracker cursor: ${cp.last_sha ? cp.last_sha.slice(0, 10) : 'none'})`,
|
|
488
481
|
`Last Action: ${ws.last_agent_action || 'none'}`,
|
|
489
482
|
`Updated: ${formatDate(ws.updated_at || ticket.updated_at)}`,
|
|
483
|
+
...(localPlan ? [
|
|
484
|
+
`Plan: ${localPlan.title} (${localPlan.tasks_done}/${localPlan.tasks_total})`,
|
|
485
|
+
`World: ${world?.snapshot_id || 'local'} · Merkle ${world?.merkle_root ? world.merkle_root.slice(0, 20) + '…' : 'unknown'}`,
|
|
486
|
+
`Knowledge: ${world?.knowledge_freshness?.status || 'unknown'}${world?.knowledge_freshness?.reason ? ' (' + world.knowledge_freshness.reason + ')' : ''}`,
|
|
487
|
+
`Actions: ${world?.actions?.available?.length || 0} available · ${world?.actions?.blocked?.length || 0} blocked`,
|
|
488
|
+
] : []),
|
|
490
489
|
'--------------------------------------------------------------------------------',
|
|
491
490
|
...(!ticket.id && !ws.current_task_id ? [
|
|
492
491
|
' No active goal. What are you trying to achieve?',
|
|
@@ -499,7 +498,7 @@ export function renderGoapStatus(state = {}) {
|
|
|
499
498
|
: [' (no commits ingested yet)']),
|
|
500
499
|
...(state.stepsUnavailable
|
|
501
500
|
? ['--------------------------------------------------------------------------------',
|
|
502
|
-
' (note: step/plan linkage unavailable
|
|
501
|
+
' (note: remote step/plan linkage is unavailable for this repository)']
|
|
503
502
|
: []),
|
|
504
503
|
'================================================================================',
|
|
505
504
|
].join('\n');
|