@senpi/trading-runtime 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +117 -0
- package/dist/actions/decision-engine.d.ts +28 -0
- package/dist/actions/decision-engine.d.ts.map +1 -0
- package/dist/actions/decision-engine.js +65 -0
- package/dist/actions/decision-engine.js.map +1 -0
- package/dist/actions/llm-decision/anthropic-llm-decision.d.ts +12 -0
- package/dist/actions/llm-decision/anthropic-llm-decision.d.ts.map +1 -0
- package/dist/actions/llm-decision/anthropic-llm-decision.js +74 -0
- package/dist/actions/llm-decision/anthropic-llm-decision.js.map +1 -0
- package/dist/actions/llm-decision/factory.d.ts +17 -0
- package/dist/actions/llm-decision/factory.d.ts.map +1 -0
- package/dist/actions/llm-decision/factory.js +29 -0
- package/dist/actions/llm-decision/factory.js.map +1 -0
- package/dist/actions/llm-decision/index.d.ts +8 -0
- package/dist/actions/llm-decision/index.d.ts.map +1 -0
- package/dist/actions/llm-decision/index.js +5 -0
- package/dist/actions/llm-decision/index.js.map +1 -0
- package/dist/actions/llm-decision/openclaw-llm-decision.d.ts +14 -0
- package/dist/actions/llm-decision/openclaw-llm-decision.d.ts.map +1 -0
- package/dist/actions/llm-decision/openclaw-llm-decision.js +58 -0
- package/dist/actions/llm-decision/openclaw-llm-decision.js.map +1 -0
- package/dist/actions/llm-decision/shared.d.ts +41 -0
- package/dist/actions/llm-decision/shared.d.ts.map +1 -0
- package/dist/actions/llm-decision/shared.js +117 -0
- package/dist/actions/llm-decision/shared.js.map +1 -0
- package/dist/actions/open-position/open-position.action.d.ts +15 -0
- package/dist/actions/open-position/open-position.action.d.ts.map +1 -0
- package/dist/actions/open-position/open-position.action.js +302 -0
- package/dist/actions/open-position/open-position.action.js.map +1 -0
- package/dist/actions/types.d.ts +123 -0
- package/dist/actions/types.d.ts.map +1 -0
- package/dist/actions/types.js +3 -0
- package/dist/actions/types.js.map +1 -0
- package/dist/cli/guide-commands.d.ts +26 -0
- package/dist/cli/guide-commands.d.ts.map +1 -0
- package/dist/cli/guide-commands.js +332 -0
- package/dist/cli/guide-commands.js.map +1 -0
- package/dist/cli/senpi-commands.d.ts +22 -0
- package/dist/cli/senpi-commands.d.ts.map +1 -0
- package/dist/cli/senpi-commands.js +138 -0
- package/dist/cli/senpi-commands.js.map +1 -0
- package/dist/constants/dsl/index.d.ts +39 -0
- package/dist/constants/dsl/index.d.ts.map +1 -0
- package/dist/constants/dsl/index.js +39 -0
- package/dist/constants/dsl/index.js.map +1 -0
- package/dist/context/context-builder.d.ts +14 -0
- package/dist/context/context-builder.d.ts.map +1 -0
- package/dist/context/context-builder.js +36 -0
- package/dist/context/context-builder.js.map +1 -0
- package/dist/context/index.d.ts +5 -0
- package/dist/context/index.d.ts.map +1 -0
- package/dist/context/index.js +5 -0
- package/dist/context/index.js.map +1 -0
- package/dist/context/interpolate.d.ts +6 -0
- package/dist/context/interpolate.d.ts.map +1 -0
- package/dist/context/interpolate.js +15 -0
- package/dist/context/interpolate.js.map +1 -0
- package/dist/context/providers/asset-trend.provider.d.ts +42 -0
- package/dist/context/providers/asset-trend.provider.d.ts.map +1 -0
- package/dist/context/providers/asset-trend.provider.js +94 -0
- package/dist/context/providers/asset-trend.provider.js.map +1 -0
- package/dist/context/providers/index.d.ts +5 -0
- package/dist/context/providers/index.d.ts.map +1 -0
- package/dist/context/providers/index.js +5 -0
- package/dist/context/providers/index.js.map +1 -0
- package/dist/context/providers/regime.provider.d.ts +14 -0
- package/dist/context/providers/regime.provider.d.ts.map +1 -0
- package/dist/context/providers/regime.provider.js +29 -0
- package/dist/context/providers/regime.provider.js.map +1 -0
- package/dist/context/providers/signal.provider.d.ts +11 -0
- package/dist/context/providers/signal.provider.d.ts.map +1 -0
- package/dist/context/providers/signal.provider.js +27 -0
- package/dist/context/providers/signal.provider.js.map +1 -0
- package/dist/context/providers/strategy.provider.d.ts +14 -0
- package/dist/context/providers/strategy.provider.d.ts.map +1 -0
- package/dist/context/providers/strategy.provider.js +68 -0
- package/dist/context/providers/strategy.provider.js.map +1 -0
- package/dist/context/types.d.ts +30 -0
- package/dist/context/types.d.ts.map +1 -0
- package/dist/context/types.js +2 -0
- package/dist/context/types.js.map +1 -0
- package/dist/dsl/config/index.d.ts +43 -0
- package/dist/dsl/config/index.d.ts.map +1 -0
- package/dist/dsl/config/index.js +108 -0
- package/dist/dsl/config/index.js.map +1 -0
- package/dist/dsl/constants/index.d.ts +3 -0
- package/dist/dsl/constants/index.d.ts.map +1 -0
- package/dist/dsl/constants/index.js +3 -0
- package/dist/dsl/constants/index.js.map +1 -0
- package/dist/dsl/engine/index.d.ts +7 -0
- package/dist/dsl/engine/index.d.ts.map +1 -0
- package/dist/dsl/engine/index.js +123 -0
- package/dist/dsl/engine/index.js.map +1 -0
- package/dist/dsl/events/bus-types.d.ts +7 -0
- package/dist/dsl/events/bus-types.d.ts.map +1 -0
- package/dist/dsl/events/bus-types.js +6 -0
- package/dist/dsl/events/bus-types.js.map +1 -0
- package/dist/dsl/events/guards.d.ts +17 -0
- package/dist/dsl/events/guards.d.ts.map +1 -0
- package/dist/dsl/events/guards.js +94 -0
- package/dist/dsl/events/guards.js.map +1 -0
- package/dist/dsl/events/handlers.d.ts +15 -0
- package/dist/dsl/events/handlers.d.ts.map +1 -0
- package/dist/dsl/events/handlers.js +229 -0
- package/dist/dsl/events/handlers.js.map +1 -0
- package/dist/dsl/events/index.d.ts +4 -0
- package/dist/dsl/events/index.d.ts.map +1 -0
- package/dist/dsl/events/index.js +4 -0
- package/dist/dsl/events/index.js.map +1 -0
- package/dist/dsl/index.d.ts +13 -0
- package/dist/dsl/index.d.ts.map +1 -0
- package/dist/dsl/index.js +35 -0
- package/dist/dsl/index.js.map +1 -0
- package/dist/dsl/monitor/index.d.ts +18 -0
- package/dist/dsl/monitor/index.d.ts.map +1 -0
- package/dist/dsl/monitor/index.js +296 -0
- package/dist/dsl/monitor/index.js.map +1 -0
- package/dist/dsl/plugin/index.d.ts +29 -0
- package/dist/dsl/plugin/index.d.ts.map +1 -0
- package/dist/dsl/plugin/index.js +85 -0
- package/dist/dsl/plugin/index.js.map +1 -0
- package/dist/dsl/types/index.d.ts +3 -0
- package/dist/dsl/types/index.d.ts.map +1 -0
- package/dist/dsl/types/index.js +3 -0
- package/dist/dsl/types/index.js.map +1 -0
- package/dist/health/index.d.ts +9 -0
- package/dist/health/index.d.ts.map +1 -0
- package/dist/health/index.js +9 -0
- package/dist/health/index.js.map +1 -0
- package/dist/index.d.ts +94 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +218 -0
- package/dist/index.js.map +1 -0
- package/dist/risk/index.d.ts +9 -0
- package/dist/risk/index.d.ts.map +1 -0
- package/dist/risk/index.js +9 -0
- package/dist/risk/index.js.map +1 -0
- package/dist/runtime/action-registry.d.ts +12 -0
- package/dist/runtime/action-registry.d.ts.map +1 -0
- package/dist/runtime/action-registry.js +18 -0
- package/dist/runtime/action-registry.js.map +1 -0
- package/dist/runtime/build-action-scan-payload.d.ts +20 -0
- package/dist/runtime/build-action-scan-payload.d.ts.map +1 -0
- package/dist/runtime/build-action-scan-payload.js +52 -0
- package/dist/runtime/build-action-scan-payload.js.map +1 -0
- package/dist/runtime/bus.d.ts +6 -0
- package/dist/runtime/bus.d.ts.map +1 -0
- package/dist/runtime/bus.js +19 -0
- package/dist/runtime/bus.js.map +1 -0
- package/dist/runtime/create-action-context.d.ts +34 -0
- package/dist/runtime/create-action-context.d.ts.map +1 -0
- package/dist/runtime/create-action-context.js +22 -0
- package/dist/runtime/create-action-context.js.map +1 -0
- package/dist/runtime/create-actions.d.ts +30 -0
- package/dist/runtime/create-actions.d.ts.map +1 -0
- package/dist/runtime/create-actions.js +78 -0
- package/dist/runtime/create-actions.js.map +1 -0
- package/dist/runtime/create-runtime-context.d.ts +33 -0
- package/dist/runtime/create-runtime-context.d.ts.map +1 -0
- package/dist/runtime/create-runtime-context.js +32 -0
- package/dist/runtime/create-runtime-context.js.map +1 -0
- package/dist/runtime/create-scanner-module.d.ts +14 -0
- package/dist/runtime/create-scanner-module.d.ts.map +1 -0
- package/dist/runtime/create-scanner-module.js +26 -0
- package/dist/runtime/create-scanner-module.js.map +1 -0
- package/dist/runtime/create-scanner-providers-for-run.d.ts +20 -0
- package/dist/runtime/create-scanner-providers-for-run.d.ts.map +1 -0
- package/dist/runtime/create-scanner-providers-for-run.js +34 -0
- package/dist/runtime/create-scanner-providers-for-run.js.map +1 -0
- package/dist/runtime/default-state-dir.d.ts +10 -0
- package/dist/runtime/default-state-dir.d.ts.map +1 -0
- package/dist/runtime/default-state-dir.js +22 -0
- package/dist/runtime/default-state-dir.js.map +1 -0
- package/dist/runtime/env-resolve.d.ts +17 -0
- package/dist/runtime/env-resolve.d.ts.map +1 -0
- package/dist/runtime/env-resolve.js +45 -0
- package/dist/runtime/env-resolve.js.map +1 -0
- package/dist/runtime/hook-system.d.ts +7 -0
- package/dist/runtime/hook-system.d.ts.map +1 -0
- package/dist/runtime/hook-system.js +16 -0
- package/dist/runtime/hook-system.js.map +1 -0
- package/dist/runtime/index.d.ts +37 -0
- package/dist/runtime/index.d.ts.map +1 -0
- package/dist/runtime/index.js +26 -0
- package/dist/runtime/index.js.map +1 -0
- package/dist/runtime/load-trading-strategy.d.ts +18 -0
- package/dist/runtime/load-trading-strategy.d.ts.map +1 -0
- package/dist/runtime/load-trading-strategy.js +51 -0
- package/dist/runtime/load-trading-strategy.js.map +1 -0
- package/dist/runtime/map-exit-config.d.ts +12 -0
- package/dist/runtime/map-exit-config.d.ts.map +1 -0
- package/dist/runtime/map-exit-config.js +89 -0
- package/dist/runtime/map-exit-config.js.map +1 -0
- package/dist/runtime/map-strategies-registration.d.ts +12 -0
- package/dist/runtime/map-strategies-registration.d.ts.map +1 -0
- package/dist/runtime/map-strategies-registration.js +52 -0
- package/dist/runtime/map-strategies-registration.js.map +1 -0
- package/dist/runtime/map-strategies.d.ts +12 -0
- package/dist/runtime/map-strategies.d.ts.map +1 -0
- package/dist/runtime/map-strategies.js +46 -0
- package/dist/runtime/map-strategies.js.map +1 -0
- package/dist/runtime/notifications.d.ts +10 -0
- package/dist/runtime/notifications.d.ts.map +1 -0
- package/dist/runtime/notifications.js +14 -0
- package/dist/runtime/notifications.js.map +1 -0
- package/dist/runtime/parse-interval.d.ts +11 -0
- package/dist/runtime/parse-interval.d.ts.map +1 -0
- package/dist/runtime/parse-interval.js +35 -0
- package/dist/runtime/parse-interval.js.map +1 -0
- package/dist/runtime/reconcile-state.d.ts +25 -0
- package/dist/runtime/reconcile-state.d.ts.map +1 -0
- package/dist/runtime/reconcile-state.js +114 -0
- package/dist/runtime/reconcile-state.js.map +1 -0
- package/dist/runtime/risk-guard.d.ts +6 -0
- package/dist/runtime/risk-guard.d.ts.map +1 -0
- package/dist/runtime/risk-guard.js +14 -0
- package/dist/runtime/risk-guard.js.map +1 -0
- package/dist/runtime/run.d.ts +21 -0
- package/dist/runtime/run.d.ts.map +1 -0
- package/dist/runtime/run.js +43 -0
- package/dist/runtime/run.js.map +1 -0
- package/dist/runtime/runtime.d.ts +40 -0
- package/dist/runtime/runtime.d.ts.map +1 -0
- package/dist/runtime/runtime.js +249 -0
- package/dist/runtime/runtime.js.map +1 -0
- package/dist/runtime/scanner-registry.d.ts +22 -0
- package/dist/runtime/scanner-registry.d.ts.map +1 -0
- package/dist/runtime/scanner-registry.js +72 -0
- package/dist/runtime/scanner-registry.js.map +1 -0
- package/dist/runtime/strategy-registry.d.ts +49 -0
- package/dist/runtime/strategy-registry.d.ts.map +1 -0
- package/dist/runtime/strategy-registry.js +150 -0
- package/dist/runtime/strategy-registry.js.map +1 -0
- package/dist/runtime/trading-strategy-config.d.ts +6 -0
- package/dist/runtime/trading-strategy-config.d.ts.map +1 -0
- package/dist/runtime/trading-strategy-config.js +5 -0
- package/dist/runtime/trading-strategy-config.js.map +1 -0
- package/dist/runtime/trading-strategy-schema.d.ts +19757 -0
- package/dist/runtime/trading-strategy-schema.d.ts.map +1 -0
- package/dist/runtime/trading-strategy-schema.js +107 -0
- package/dist/runtime/trading-strategy-schema.js.map +1 -0
- package/dist/scanners/__tests__/fixtures/index.d.ts +3 -0
- package/dist/scanners/__tests__/fixtures/index.d.ts.map +1 -0
- package/dist/scanners/__tests__/fixtures/index.js +3 -0
- package/dist/scanners/__tests__/fixtures/index.js.map +1 -0
- package/dist/scanners/__tests__/fixtures/scan-results.d.ts +23 -0
- package/dist/scanners/__tests__/fixtures/scan-results.d.ts.map +1 -0
- package/dist/scanners/__tests__/fixtures/scan-results.js +128 -0
- package/dist/scanners/__tests__/fixtures/scan-results.js.map +1 -0
- package/dist/scanners/__tests__/fixtures/signals.d.ts +18 -0
- package/dist/scanners/__tests__/fixtures/signals.d.ts.map +1 -0
- package/dist/scanners/__tests__/fixtures/signals.js +84 -0
- package/dist/scanners/__tests__/fixtures/signals.js.map +1 -0
- package/dist/scanners/__tests__/test-helpers.d.ts +4 -0
- package/dist/scanners/__tests__/test-helpers.d.ts.map +1 -0
- package/dist/scanners/__tests__/test-helpers.js +23 -0
- package/dist/scanners/__tests__/test-helpers.js.map +1 -0
- package/dist/scanners/artifacts.d.ts +119 -0
- package/dist/scanners/artifacts.d.ts.map +1 -0
- package/dist/scanners/artifacts.js +72 -0
- package/dist/scanners/artifacts.js.map +1 -0
- package/dist/scanners/create-scanner.d.ts +13 -0
- package/dist/scanners/create-scanner.d.ts.map +1 -0
- package/dist/scanners/create-scanner.js +11 -0
- package/dist/scanners/create-scanner.js.map +1 -0
- package/dist/scanners/engine/config-validator.d.ts +7 -0
- package/dist/scanners/engine/config-validator.d.ts.map +1 -0
- package/dist/scanners/engine/config-validator.js +16 -0
- package/dist/scanners/engine/config-validator.js.map +1 -0
- package/dist/scanners/engine/data-providers.d.ts +43 -0
- package/dist/scanners/engine/data-providers.d.ts.map +1 -0
- package/dist/scanners/engine/data-providers.js +8 -0
- package/dist/scanners/engine/data-providers.js.map +1 -0
- package/dist/scanners/engine/engine.d.ts +76 -0
- package/dist/scanners/engine/engine.d.ts.map +1 -0
- package/dist/scanners/engine/engine.js +399 -0
- package/dist/scanners/engine/engine.js.map +1 -0
- package/dist/scanners/engine/index.d.ts +9 -0
- package/dist/scanners/engine/index.d.ts.map +1 -0
- package/dist/scanners/engine/index.js +7 -0
- package/dist/scanners/engine/index.js.map +1 -0
- package/dist/scanners/engine/input-resolver.d.ts +21 -0
- package/dist/scanners/engine/input-resolver.d.ts.map +1 -0
- package/dist/scanners/engine/input-resolver.js +140 -0
- package/dist/scanners/engine/input-resolver.js.map +1 -0
- package/dist/scanners/engine/lifecycle.d.ts +21 -0
- package/dist/scanners/engine/lifecycle.d.ts.map +1 -0
- package/dist/scanners/engine/lifecycle.js +2 -0
- package/dist/scanners/engine/lifecycle.js.map +1 -0
- package/dist/scanners/engine/result-builder.d.ts +30 -0
- package/dist/scanners/engine/result-builder.d.ts.map +1 -0
- package/dist/scanners/engine/result-builder.js +129 -0
- package/dist/scanners/engine/result-builder.js.map +1 -0
- package/dist/scanners/engine/strategy-registry.d.ts +45 -0
- package/dist/scanners/engine/strategy-registry.d.ts.map +1 -0
- package/dist/scanners/engine/strategy-registry.js +93 -0
- package/dist/scanners/engine/strategy-registry.js.map +1 -0
- package/dist/scanners/events.d.ts +41 -0
- package/dist/scanners/events.d.ts.map +1 -0
- package/dist/scanners/events.js +33 -0
- package/dist/scanners/events.js.map +1 -0
- package/dist/scanners/implementations/emerging-movers.d.ts +212 -0
- package/dist/scanners/implementations/emerging-movers.d.ts.map +1 -0
- package/dist/scanners/implementations/emerging-movers.js +702 -0
- package/dist/scanners/implementations/emerging-movers.js.map +1 -0
- package/dist/scanners/implementations/index.d.ts +8 -0
- package/dist/scanners/implementations/index.d.ts.map +1 -0
- package/dist/scanners/implementations/index.js +8 -0
- package/dist/scanners/implementations/index.js.map +1 -0
- package/dist/scanners/implementations/indicators.d.ts +40 -0
- package/dist/scanners/implementations/indicators.d.ts.map +1 -0
- package/dist/scanners/implementations/indicators.js +114 -0
- package/dist/scanners/implementations/indicators.js.map +1 -0
- package/dist/scanners/implementations/market-regime.d.ts +52 -0
- package/dist/scanners/implementations/market-regime.d.ts.map +1 -0
- package/dist/scanners/implementations/market-regime.js +201 -0
- package/dist/scanners/implementations/market-regime.js.map +1 -0
- package/dist/scanners/implementations/momentum.d.ts +21 -0
- package/dist/scanners/implementations/momentum.d.ts.map +1 -0
- package/dist/scanners/implementations/momentum.js +128 -0
- package/dist/scanners/implementations/momentum.js.map +1 -0
- package/dist/scanners/implementations/oi-tracker.d.ts +13 -0
- package/dist/scanners/implementations/oi-tracker.d.ts.map +1 -0
- package/dist/scanners/implementations/oi-tracker.js +67 -0
- package/dist/scanners/implementations/oi-tracker.js.map +1 -0
- package/dist/scanners/implementations/opportunity.d.ts +104 -0
- package/dist/scanners/implementations/opportunity.d.ts.map +1 -0
- package/dist/scanners/implementations/opportunity.js +441 -0
- package/dist/scanners/implementations/opportunity.js.map +1 -0
- package/dist/scanners/implementations/prescreener.d.ts +20 -0
- package/dist/scanners/implementations/prescreener.d.ts.map +1 -0
- package/dist/scanners/implementations/prescreener.js +97 -0
- package/dist/scanners/implementations/prescreener.js.map +1 -0
- package/dist/scanners/implementations/sm-flip.d.ts +43 -0
- package/dist/scanners/implementations/sm-flip.d.ts.map +1 -0
- package/dist/scanners/implementations/sm-flip.js +200 -0
- package/dist/scanners/implementations/sm-flip.js.map +1 -0
- package/dist/scanners/index.d.ts +24 -0
- package/dist/scanners/index.d.ts.map +1 -0
- package/dist/scanners/index.js +17 -0
- package/dist/scanners/index.js.map +1 -0
- package/dist/scanners/input-descriptors.d.ts +49 -0
- package/dist/scanners/input-descriptors.d.ts.map +1 -0
- package/dist/scanners/input-descriptors.js +35 -0
- package/dist/scanners/input-descriptors.js.map +1 -0
- package/dist/scanners/protocol/context.d.ts +71 -0
- package/dist/scanners/protocol/context.d.ts.map +1 -0
- package/dist/scanners/protocol/context.js +2 -0
- package/dist/scanners/protocol/context.js.map +1 -0
- package/dist/scanners/protocol/hooks.d.ts +18 -0
- package/dist/scanners/protocol/hooks.d.ts.map +1 -0
- package/dist/scanners/protocol/hooks.js +12 -0
- package/dist/scanners/protocol/hooks.js.map +1 -0
- package/dist/scanners/protocol/index.d.ts +5 -0
- package/dist/scanners/protocol/index.d.ts.map +1 -0
- package/dist/scanners/protocol/index.js +2 -0
- package/dist/scanners/protocol/index.js.map +1 -0
- package/dist/scanners/protocol/scanner.d.ts +47 -0
- package/dist/scanners/protocol/scanner.d.ts.map +1 -0
- package/dist/scanners/protocol/scanner.js +2 -0
- package/dist/scanners/protocol/scanner.js.map +1 -0
- package/dist/scanners/providers/adapter.d.ts +23 -0
- package/dist/scanners/providers/adapter.d.ts.map +1 -0
- package/dist/scanners/providers/adapter.js +227 -0
- package/dist/scanners/providers/adapter.js.map +1 -0
- package/dist/scanners/providers/cache.d.ts +20 -0
- package/dist/scanners/providers/cache.d.ts.map +1 -0
- package/dist/scanners/providers/cache.js +61 -0
- package/dist/scanners/providers/cache.js.map +1 -0
- package/dist/scanners/providers/client.d.ts +53 -0
- package/dist/scanners/providers/client.d.ts.map +1 -0
- package/dist/scanners/providers/client.js +174 -0
- package/dist/scanners/providers/client.js.map +1 -0
- package/dist/scanners/providers/factory.d.ts +42 -0
- package/dist/scanners/providers/factory.d.ts.map +1 -0
- package/dist/scanners/providers/factory.js +156 -0
- package/dist/scanners/providers/factory.js.map +1 -0
- package/dist/scanners/providers/types.d.ts +61 -0
- package/dist/scanners/providers/types.d.ts.map +1 -0
- package/dist/scanners/providers/types.js +6 -0
- package/dist/scanners/providers/types.js.map +1 -0
- package/dist/scanners/runtime-module.d.ts +54 -0
- package/dist/scanners/runtime-module.d.ts.map +1 -0
- package/dist/scanners/runtime-module.js +94 -0
- package/dist/scanners/runtime-module.js.map +1 -0
- package/dist/scanners/scanner-definition.d.ts +58 -0
- package/dist/scanners/scanner-definition.d.ts.map +1 -0
- package/dist/scanners/scanner-definition.js +19 -0
- package/dist/scanners/scanner-definition.js.map +1 -0
- package/dist/scanners/schema-utils.d.ts +6 -0
- package/dist/scanners/schema-utils.d.ts.map +1 -0
- package/dist/scanners/schema-utils.js +14 -0
- package/dist/scanners/schema-utils.js.map +1 -0
- package/dist/scanners/score-utils.d.ts +19 -0
- package/dist/scanners/score-utils.d.ts.map +1 -0
- package/dist/scanners/score-utils.js +47 -0
- package/dist/scanners/score-utils.js.map +1 -0
- package/dist/scanners/store/fs-utils.d.ts +12 -0
- package/dist/scanners/store/fs-utils.d.ts.map +1 -0
- package/dist/scanners/store/fs-utils.js +47 -0
- package/dist/scanners/store/fs-utils.js.map +1 -0
- package/dist/scanners/store/index.d.ts +5 -0
- package/dist/scanners/store/index.d.ts.map +1 -0
- package/dist/scanners/store/index.js +5 -0
- package/dist/scanners/store/index.js.map +1 -0
- package/dist/scanners/store/runtime-store.d.ts +50 -0
- package/dist/scanners/store/runtime-store.d.ts.map +1 -0
- package/dist/scanners/store/runtime-store.js +91 -0
- package/dist/scanners/store/runtime-store.js.map +1 -0
- package/dist/scanners/store/shared-artifact-store.d.ts +31 -0
- package/dist/scanners/store/shared-artifact-store.d.ts.map +1 -0
- package/dist/scanners/store/shared-artifact-store.js +89 -0
- package/dist/scanners/store/shared-artifact-store.js.map +1 -0
- package/dist/scanners/store/signal-store.d.ts +36 -0
- package/dist/scanners/store/signal-store.d.ts.map +1 -0
- package/dist/scanners/store/signal-store.js +135 -0
- package/dist/scanners/store/signal-store.js.map +1 -0
- package/dist/scanners/types.d.ts +115 -0
- package/dist/scanners/types.d.ts.map +1 -0
- package/dist/scanners/types.js +3 -0
- package/dist/scanners/types.js.map +1 -0
- package/dist/scripts/run-dsl-standalone-live.d.ts +27 -0
- package/dist/scripts/run-dsl-standalone-live.d.ts.map +1 -0
- package/dist/scripts/run-dsl-standalone-live.js +207 -0
- package/dist/scripts/run-dsl-standalone-live.js.map +1 -0
- package/dist/scripts/run-dsl-standalone-mock.d.ts +13 -0
- package/dist/scripts/run-dsl-standalone-mock.d.ts.map +1 -0
- package/dist/scripts/run-dsl-standalone-mock.js +255 -0
- package/dist/scripts/run-dsl-standalone-mock.js.map +1 -0
- package/dist/senpi/client.d.ts +70 -0
- package/dist/senpi/client.d.ts.map +1 -0
- package/dist/senpi/client.js +482 -0
- package/dist/senpi/client.js.map +1 -0
- package/dist/senpi/constants.d.ts +7 -0
- package/dist/senpi/constants.d.ts.map +1 -0
- package/dist/senpi/constants.js +7 -0
- package/dist/senpi/constants.js.map +1 -0
- package/dist/senpi/index.d.ts +3 -0
- package/dist/senpi/index.d.ts.map +1 -0
- package/dist/senpi/index.js +2 -0
- package/dist/senpi/index.js.map +1 -0
- package/dist/senpi/types.d.ts +132 -0
- package/dist/senpi/types.d.ts.map +1 -0
- package/dist/senpi/types.js +3 -0
- package/dist/senpi/types.js.map +1 -0
- package/dist/state/index.d.ts +3 -0
- package/dist/state/index.d.ts.map +1 -0
- package/dist/state/index.js +3 -0
- package/dist/state/index.js.map +1 -0
- package/dist/state/paths.d.ts +8 -0
- package/dist/state/paths.d.ts.map +1 -0
- package/dist/state/paths.js +19 -0
- package/dist/state/paths.js.map +1 -0
- package/dist/state/state-manager.d.ts +56 -0
- package/dist/state/state-manager.d.ts.map +1 -0
- package/dist/state/state-manager.js +213 -0
- package/dist/state/state-manager.js.map +1 -0
- package/dist/strategy/index.d.ts +2 -0
- package/dist/strategy/index.d.ts.map +1 -0
- package/dist/strategy/index.js +2 -0
- package/dist/strategy/index.js.map +1 -0
- package/dist/strategy/strategy-state.d.ts +47 -0
- package/dist/strategy/strategy-state.d.ts.map +1 -0
- package/dist/strategy/strategy-state.js +179 -0
- package/dist/strategy/strategy-state.js.map +1 -0
- package/dist/types/action.d.ts +15 -0
- package/dist/types/action.d.ts.map +1 -0
- package/dist/types/action.js +2 -0
- package/dist/types/action.js.map +1 -0
- package/dist/types/dsl/index.d.ts +156 -0
- package/dist/types/dsl/index.d.ts.map +1 -0
- package/dist/types/dsl/index.js +5 -0
- package/dist/types/dsl/index.js.map +1 -0
- package/dist/types/event-bus.d.ts +11 -0
- package/dist/types/event-bus.d.ts.map +1 -0
- package/dist/types/event-bus.js +6 -0
- package/dist/types/event-bus.js.map +1 -0
- package/dist/types/hooks.d.ts +27 -0
- package/dist/types/hooks.d.ts.map +1 -0
- package/dist/types/hooks.js +15 -0
- package/dist/types/hooks.js.map +1 -0
- package/dist/types/index.d.ts +6 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +6 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/notification.d.ts +4 -0
- package/dist/types/notification.d.ts.map +1 -0
- package/dist/types/notification.js +3 -0
- package/dist/types/notification.js.map +1 -0
- package/dist/types/runtime.d.ts +16 -0
- package/dist/types/runtime.d.ts.map +1 -0
- package/dist/types/runtime.js +2 -0
- package/dist/types/runtime.js.map +1 -0
- package/dist/types/scanner.d.ts +59 -0
- package/dist/types/scanner.d.ts.map +1 -0
- package/dist/types/scanner.js +13 -0
- package/dist/types/scanner.js.map +1 -0
- package/dist/types/strategy.d.ts +97 -0
- package/dist/types/strategy.d.ts.map +1 -0
- package/dist/types/strategy.js +2 -0
- package/dist/types/strategy.js.map +1 -0
- package/dist/utils/logger/dsl.d.ts +8 -0
- package/dist/utils/logger/dsl.d.ts.map +1 -0
- package/dist/utils/logger/dsl.js +7 -0
- package/dist/utils/logger/dsl.js.map +1 -0
- package/dist/utils/logger.d.ts +13 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +65 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/response.d.ts +14 -0
- package/dist/utils/response.d.ts.map +1 -0
- package/dist/utils/response.js +44 -0
- package/dist/utils/response.js.map +1 -0
- package/dist/version.d.ts +2 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +2 -0
- package/dist/version.js.map +1 -0
- package/examples/.env.example +15 -0
- package/examples/README.md +75 -0
- package/examples/scanners-consumer-quickstart.mjs +134 -0
- package/examples/scanners-emerging-movers-v4.mjs +285 -0
- package/examples/scanners-live-mcp.mjs +208 -0
- package/examples/scanners-multi-strategy.mjs +165 -0
- package/examples/scanners-scheduled-events.mjs +95 -0
- package/examples/scanners-senpi-provider-client.mjs +182 -0
- package/examples/scanners-single-strategy.mjs +198 -0
- package/examples/strategies/README.md +45 -0
- package/examples/strategies/dsl-showcase.yaml +62 -0
- package/examples/strategies/fox.yaml +55 -0
- package/examples/strategies/minimal.yaml +41 -0
- package/examples/strategies/viper.yaml +63 -0
- package/examples/strategies/wolf.yaml +60 -0
- package/examples/yamls/sample-with-dsl-and-emerging-movers.yaml +111 -0
- package/openclaw.plugin.json +15 -0
- package/package.json +52 -0
package/README.md
ADDED
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
# @senpi/trading-runtime
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/@senpi/trading-runtime)
|
|
4
|
+
|
|
5
|
+
Event-driven automated trading plugin for OpenClaw. Orchestrates scanners, LLM-based trade decisions, and a DSL trailing stop-loss exit engine.
|
|
6
|
+
|
|
7
|
+
## Prerequisites
|
|
8
|
+
|
|
9
|
+
- **OpenClaw** >= 2026.2.0
|
|
10
|
+
- **Node** >= 22
|
|
11
|
+
- **Senpi API key** (for live trading)
|
|
12
|
+
|
|
13
|
+
## Install
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
openclaw plugins install @senpi/trading-runtime
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Configure
|
|
20
|
+
|
|
21
|
+
Add the plugin to your OpenClaw config (e.g. `~/.openclaw/openclaw.json` or via `openclaw config set`). Use the plugin **id** `trading-runtime` as the key:
|
|
22
|
+
|
|
23
|
+
```json
|
|
24
|
+
{
|
|
25
|
+
"plugins": {
|
|
26
|
+
"entries": {
|
|
27
|
+
"trading-runtime": {
|
|
28
|
+
"enabled": true,
|
|
29
|
+
"config": {
|
|
30
|
+
"stateDir": "~/.openclaw/senpi-state",
|
|
31
|
+
"apiKey": "YOUR_SENPI_API_KEY"
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Quickstart
|
|
40
|
+
|
|
41
|
+
1. Copy a minimal strategy template and set your wallet:
|
|
42
|
+
```bash
|
|
43
|
+
cp $(openclaw plugins path @senpi/trading-runtime)/examples/strategies/minimal.yaml ~/my-strategy.yaml
|
|
44
|
+
# Edit my-strategy.yaml: replace ${WALLET_ADDRESS} or set WALLET_ADDRESS in env
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
2. Set environment variables (e.g. `.env`): `SENPI_API_KEY`, `WALLET_ADDRESS`.
|
|
48
|
+
|
|
49
|
+
3. Load the strategy (hot-loads; no gateway restart):
|
|
50
|
+
```bash
|
|
51
|
+
openclaw senpi trading-strategy create -p ~/my-strategy.yaml
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
4. List strategies:
|
|
55
|
+
```bash
|
|
56
|
+
openclaw senpi trading-strategy list
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
5. Watch gateway logs for scanner runs and signal processing.
|
|
60
|
+
|
|
61
|
+
## Strategy templates
|
|
62
|
+
|
|
63
|
+
| File | Style | Scanners | Use case |
|
|
64
|
+
|------|-------|----------|----------|
|
|
65
|
+
| minimal.yaml | Watch-only | emerging_movers | Verify setup; no positions |
|
|
66
|
+
| wolf.yaml | Aggressive | emerging_movers | Early entry on FIRST_JUMP |
|
|
67
|
+
| viper.yaml | Moderate | prescreener + momentum | Candle-based breakouts |
|
|
68
|
+
| fox.yaml | OI-driven | prescreener + oi_tracker | OI-driven entries |
|
|
69
|
+
| dsl-showcase.yaml | DSL reference | emerging_movers | Annotated exit config |
|
|
70
|
+
|
|
71
|
+
Templates live under `examples/strategies/` in the package. See [examples/strategies/README.md](examples/strategies/README.md).
|
|
72
|
+
|
|
73
|
+
## CLI reference
|
|
74
|
+
|
|
75
|
+
**Trading strategies:**
|
|
76
|
+
- `openclaw senpi trading-strategy create -p <path>` — create from YAML file (hot-load)
|
|
77
|
+
- `openclaw senpi trading-strategy create -c "<yaml>"` — create from inline YAML
|
|
78
|
+
- `openclaw senpi trading-strategy list` — list installed strategies
|
|
79
|
+
- `openclaw senpi trading-strategy uninstallStrategy --strategy-id <id>` — remove by id
|
|
80
|
+
|
|
81
|
+
**In-shell reference:**
|
|
82
|
+
- `openclaw senpi guide` — overview
|
|
83
|
+
- `openclaw senpi guide scanners` — scanner types and config fields
|
|
84
|
+
- `openclaw senpi guide actions` — action types and decision modes
|
|
85
|
+
- `openclaw senpi guide dsl` — DSL two-phase exit engine
|
|
86
|
+
- `openclaw senpi guide examples` — print minimal strategy YAML
|
|
87
|
+
- `openclaw senpi guide schema` — full YAML schema
|
|
88
|
+
- `openclaw senpi guide version` — plugin version and changelog URL
|
|
89
|
+
|
|
90
|
+
## Guide skill
|
|
91
|
+
|
|
92
|
+
Once published, the **@senpi-guide** skill on ClawHub provides the same reference in chat. Install with `clawhub install skills/senpi-guide/` (or from the ClawHub UI).
|
|
93
|
+
|
|
94
|
+
## Install on an existing OpenClaw setup
|
|
95
|
+
|
|
96
|
+
If you already have OpenClaw installed (local, VPS, or self-hosted), see [Installing on existing OpenClaw](docs/install/existing-openclaw.md) for the full install sequence, config stanza, and troubleshooting.
|
|
97
|
+
|
|
98
|
+
## Docs
|
|
99
|
+
|
|
100
|
+
- [Architecture](docs/runtime-docs/design/architecture.md)
|
|
101
|
+
- [Skills YAML schema](docs/runtime-docs/design/skills-yaml-schema.md)
|
|
102
|
+
- [Integration guide](docs/runtime-docs/integration-guide.md)
|
|
103
|
+
- [Runtime API](docs/runtime-docs/runtime-api.md)
|
|
104
|
+
|
|
105
|
+
## Changelog
|
|
106
|
+
|
|
107
|
+
[CHANGELOG.md](CHANGELOG.md)
|
|
108
|
+
|
|
109
|
+
## Development
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
npm run build # install deps + compile TypeScript
|
|
113
|
+
npm test # unit + integration tests (no credentials required)
|
|
114
|
+
npm run dev # build + run
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
Pre-commit runs `npm run build && npm test`. See [CLAUDE.md](CLAUDE.md) and [docs/runtime-docs/](docs/runtime-docs/) for conventions and design.
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { ActionDecision, ActionType, DecisionMode, HookEvent, LlmDecision } from './types.js';
|
|
2
|
+
export interface DecisionRequest {
|
|
3
|
+
prompt?: string;
|
|
4
|
+
context: Record<string, unknown>;
|
|
5
|
+
model?: string;
|
|
6
|
+
actionType: ActionType;
|
|
7
|
+
event: HookEvent;
|
|
8
|
+
}
|
|
9
|
+
export interface DecisionStrategy {
|
|
10
|
+
readonly mode: DecisionMode;
|
|
11
|
+
decide(request: DecisionRequest): Promise<ActionDecision>;
|
|
12
|
+
}
|
|
13
|
+
export declare class DecisionEngine {
|
|
14
|
+
private strategies;
|
|
15
|
+
register(strategy: DecisionStrategy): void;
|
|
16
|
+
decide(mode: DecisionMode, request: DecisionRequest): Promise<ActionDecision>;
|
|
17
|
+
}
|
|
18
|
+
export declare class LlmDecisionStrategy implements DecisionStrategy {
|
|
19
|
+
private llmDecision;
|
|
20
|
+
readonly mode: DecisionMode;
|
|
21
|
+
constructor(llmDecision: LlmDecision);
|
|
22
|
+
decide(request: DecisionRequest): Promise<ActionDecision>;
|
|
23
|
+
}
|
|
24
|
+
export declare class NoDecisionStrategy implements DecisionStrategy {
|
|
25
|
+
readonly mode: DecisionMode;
|
|
26
|
+
decide(request: DecisionRequest): Promise<ActionDecision>;
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=decision-engine.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"decision-engine.d.ts","sourceRoot":"","sources":["../../src/actions/decision-engine.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,cAAc,EACd,UAAU,EACV,YAAY,EACZ,SAAS,EACT,WAAW,EACZ,MAAM,YAAY,CAAC;AAIpB,MAAM,WAAW,eAAe;IAC9B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,UAAU,CAAC;IACvB,KAAK,EAAE,SAAS,CAAC;CAClB;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAC;IAC5B,MAAM,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;CAC3D;AAID,qBAAa,cAAc;IACzB,OAAO,CAAC,UAAU,CAA6C;IAE/D,QAAQ,CAAC,QAAQ,EAAE,gBAAgB,GAAG,IAAI;IAIpC,MAAM,CAAC,IAAI,EAAE,YAAY,EAAE,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,cAAc,CAAC;CAOpF;AAID,qBAAa,mBAAoB,YAAW,gBAAgB;IAG9C,OAAO,CAAC,WAAW;IAF/B,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAS;gBAEhB,WAAW,EAAE,WAAW;IAEtC,MAAM,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,cAAc,CAAC;CAmChE;AAID,qBAAa,kBAAmB,YAAW,gBAAgB;IACzD,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAU;IAE/B,MAAM,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,cAAc,CAAC;CAShE"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
// ─── Decision Engine ────────────────────────────────────────────────────────
|
|
2
|
+
export class DecisionEngine {
|
|
3
|
+
strategies = new Map();
|
|
4
|
+
register(strategy) {
|
|
5
|
+
this.strategies.set(strategy.mode, strategy);
|
|
6
|
+
}
|
|
7
|
+
async decide(mode, request) {
|
|
8
|
+
const strategy = this.strategies.get(mode);
|
|
9
|
+
if (!strategy) {
|
|
10
|
+
throw new Error(`No decision strategy registered for mode: ${mode}`);
|
|
11
|
+
}
|
|
12
|
+
return strategy.decide(request);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
// ─── LLM Decision Strategy ─────────────────────────────────────────────────
|
|
16
|
+
export class LlmDecisionStrategy {
|
|
17
|
+
llmDecision;
|
|
18
|
+
mode = 'llm';
|
|
19
|
+
constructor(llmDecision) {
|
|
20
|
+
this.llmDecision = llmDecision;
|
|
21
|
+
}
|
|
22
|
+
async decide(request) {
|
|
23
|
+
if (!request.prompt) {
|
|
24
|
+
throw new Error('LLM decision mode requires a prompt');
|
|
25
|
+
}
|
|
26
|
+
const response = await this.llmDecision.decide({
|
|
27
|
+
prompt: request.prompt,
|
|
28
|
+
context: request.context,
|
|
29
|
+
model: request.model,
|
|
30
|
+
});
|
|
31
|
+
const decision = response.decision;
|
|
32
|
+
if (typeof decision.execute !== 'boolean') {
|
|
33
|
+
throw new Error('LLM decision missing required field: execute');
|
|
34
|
+
}
|
|
35
|
+
if (typeof decision.confidence !== 'number' ||
|
|
36
|
+
decision.confidence < 1 ||
|
|
37
|
+
decision.confidence > 10) {
|
|
38
|
+
throw new Error('LLM decision confidence must be a number between 1 and 10');
|
|
39
|
+
}
|
|
40
|
+
if (typeof decision.reasoning !== 'string') {
|
|
41
|
+
throw new Error('LLM decision missing required field: reasoning');
|
|
42
|
+
}
|
|
43
|
+
return {
|
|
44
|
+
execute: decision.execute,
|
|
45
|
+
actionType: decision.actionType ?? request.actionType,
|
|
46
|
+
confidence: decision.confidence,
|
|
47
|
+
reasoning: decision.reasoning,
|
|
48
|
+
payload: decision.payload ?? {},
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
// ─── No Decision Strategy ───────────────────────────────────────────────────
|
|
53
|
+
export class NoDecisionStrategy {
|
|
54
|
+
mode = 'none';
|
|
55
|
+
async decide(request) {
|
|
56
|
+
return {
|
|
57
|
+
execute: false,
|
|
58
|
+
actionType: request.actionType,
|
|
59
|
+
confidence: 10,
|
|
60
|
+
reasoning: 'No decision required',
|
|
61
|
+
payload: {},
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=decision-engine.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"decision-engine.js","sourceRoot":"","sources":["../../src/actions/decision-engine.ts"],"names":[],"mappings":"AAuBA,+EAA+E;AAE/E,MAAM,OAAO,cAAc;IACjB,UAAU,GAAG,IAAI,GAAG,EAAkC,CAAC;IAE/D,QAAQ,CAAC,QAA0B;QACjC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;IAC/C,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,IAAkB,EAAE,OAAwB;QACvD,MAAM,QAAQ,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAC3C,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,MAAM,IAAI,KAAK,CAAC,6CAA6C,IAAI,EAAE,CAAC,CAAC;QACvE,CAAC;QACD,OAAO,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAClC,CAAC;CACF;AAED,8EAA8E;AAE9E,MAAM,OAAO,mBAAmB;IAGV;IAFX,IAAI,GAAiB,KAAK,CAAC;IAEpC,YAAoB,WAAwB;QAAxB,gBAAW,GAAX,WAAW,CAAa;IAAG,CAAC;IAEhD,KAAK,CAAC,MAAM,CAAC,OAAwB;QACnC,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC;YACpB,MAAM,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAC;QACzD,CAAC;QAED,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,MAAM,CAAiB;YAC7D,MAAM,EAAE,OAAO,CAAC,MAAM;YACtB,OAAO,EAAE,OAAO,CAAC,OAAO;YACxB,KAAK,EAAE,OAAO,CAAC,KAAK;SACrB,CAAC,CAAC;QAEH,MAAM,QAAQ,GAAG,QAAQ,CAAC,QAAQ,CAAC;QAEnC,IAAI,OAAO,QAAQ,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;YAC1C,MAAM,IAAI,KAAK,CAAC,8CAA8C,CAAC,CAAC;QAClE,CAAC;QACD,IACE,OAAO,QAAQ,CAAC,UAAU,KAAK,QAAQ;YACvC,QAAQ,CAAC,UAAU,GAAG,CAAC;YACvB,QAAQ,CAAC,UAAU,GAAG,EAAE,EACxB,CAAC;YACD,MAAM,IAAI,KAAK,CAAC,2DAA2D,CAAC,CAAC;QAC/E,CAAC;QACD,IAAI,OAAO,QAAQ,CAAC,SAAS,KAAK,QAAQ,EAAE,CAAC;YAC3C,MAAM,IAAI,KAAK,CAAC,gDAAgD,CAAC,CAAC;QACpE,CAAC;QAED,OAAO;YACL,OAAO,EAAE,QAAQ,CAAC,OAAO;YACzB,UAAU,EAAE,QAAQ,CAAC,UAAU,IAAI,OAAO,CAAC,UAAU;YACrD,UAAU,EAAE,QAAQ,CAAC,UAAU;YAC/B,SAAS,EAAE,QAAQ,CAAC,SAAS;YAC7B,OAAO,EAAE,QAAQ,CAAC,OAAO,IAAI,EAAE;SAChC,CAAC;IACJ,CAAC;CACF;AAED,+EAA+E;AAE/E,MAAM,OAAO,kBAAkB;IACpB,IAAI,GAAiB,MAAM,CAAC;IAErC,KAAK,CAAC,MAAM,CAAC,OAAwB;QACnC,OAAO;YACL,OAAO,EAAE,KAAK;YACd,UAAU,EAAE,OAAO,CAAC,UAAU;YAC9B,UAAU,EAAE,EAAE;YACd,SAAS,EAAE,sBAAsB;YACjC,OAAO,EAAE,EAAE;SACZ,CAAC;IACJ,CAAC;CACF"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { LlmDecision, LlmDecisionRequest, LlmDecisionResponse } from '../types.js';
|
|
2
|
+
export interface AnthropicLlmDecisionOptions {
|
|
3
|
+
apiKey?: string;
|
|
4
|
+
defaultModel?: string;
|
|
5
|
+
}
|
|
6
|
+
export declare class AnthropicLlmDecision implements LlmDecision {
|
|
7
|
+
private readonly client;
|
|
8
|
+
private readonly defaultModel;
|
|
9
|
+
constructor(options?: AnthropicLlmDecisionOptions);
|
|
10
|
+
decide<T>(request: LlmDecisionRequest): Promise<LlmDecisionResponse<T>>;
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=anthropic-llm-decision.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"anthropic-llm-decision.d.ts","sourceRoot":"","sources":["../../../src/actions/llm-decision/anthropic-llm-decision.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAGxF,MAAM,WAAW,2BAA2B;IAC1C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAKD,qBAAa,oBAAqB,YAAW,WAAW;IACtD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAY;IACnC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;gBAE1B,OAAO,CAAC,EAAE,2BAA2B;IAM3C,MAAM,CAAC,CAAC,EAAE,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC;CAgD9E"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import Anthropic from '@anthropic-ai/sdk';
|
|
2
|
+
import { ACTION_DECISION_SCHEMA, SYSTEM_PROMPT } from './shared.js';
|
|
3
|
+
const DEFAULT_MODEL = 'claude-sonnet-4-20250514';
|
|
4
|
+
const DEFAULT_MAX_TOKENS = 1024;
|
|
5
|
+
export class AnthropicLlmDecision {
|
|
6
|
+
client;
|
|
7
|
+
defaultModel;
|
|
8
|
+
constructor(options) {
|
|
9
|
+
const apiKey = options?.apiKey?.replace(/\s+/g, '');
|
|
10
|
+
this.client = new Anthropic(apiKey ? { apiKey } : undefined);
|
|
11
|
+
this.defaultModel = options?.defaultModel ?? DEFAULT_MODEL;
|
|
12
|
+
}
|
|
13
|
+
async decide(request) {
|
|
14
|
+
const start = Date.now();
|
|
15
|
+
const userContent = `## Task\n${request.prompt}\n\n## Context\n${JSON.stringify(request.context, null, 2)}`;
|
|
16
|
+
let response;
|
|
17
|
+
try {
|
|
18
|
+
response = await this.client.messages.create({
|
|
19
|
+
model: request.model ?? this.defaultModel,
|
|
20
|
+
max_tokens: request.maxTokens ?? DEFAULT_MAX_TOKENS,
|
|
21
|
+
...(request.temperature != null ? { temperature: request.temperature } : {}),
|
|
22
|
+
system: SYSTEM_PROMPT,
|
|
23
|
+
messages: [{ role: 'user', content: userContent }],
|
|
24
|
+
tools: [
|
|
25
|
+
{
|
|
26
|
+
name: 'trading_decision',
|
|
27
|
+
description: 'Submit a structured trading decision',
|
|
28
|
+
input_schema: ACTION_DECISION_SCHEMA,
|
|
29
|
+
},
|
|
30
|
+
],
|
|
31
|
+
tool_choice: { type: 'tool', name: 'trading_decision' },
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
catch (error) {
|
|
35
|
+
throw classifyAnthropicError(error);
|
|
36
|
+
}
|
|
37
|
+
const latencyMs = Date.now() - start;
|
|
38
|
+
const toolBlock = response.content.find((block) => block.type === 'tool_use');
|
|
39
|
+
if (!toolBlock) {
|
|
40
|
+
throw new Error('Anthropic response contained no tool_use block');
|
|
41
|
+
}
|
|
42
|
+
const decision = toolBlock.input;
|
|
43
|
+
const tokensUsed = response.usage.input_tokens + response.usage.output_tokens;
|
|
44
|
+
return {
|
|
45
|
+
decision,
|
|
46
|
+
rawResponse: JSON.stringify(response.content),
|
|
47
|
+
tokensUsed,
|
|
48
|
+
latencyMs,
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
// ─── Error classification ───────────────────────────────────────────────────
|
|
53
|
+
function classifyAnthropicError(error) {
|
|
54
|
+
try {
|
|
55
|
+
if (Anthropic.APIConnectionError && error instanceof Anthropic.APIConnectionError) {
|
|
56
|
+
const cause = error.cause instanceof Error ? error.cause.message : String(error.cause ?? '');
|
|
57
|
+
return new Error(`Anthropic connection failed: ${cause || error.message}`);
|
|
58
|
+
}
|
|
59
|
+
if (Anthropic.AuthenticationError && error instanceof Anthropic.AuthenticationError) {
|
|
60
|
+
return new Error(`Anthropic authentication failed: ${error.message}`);
|
|
61
|
+
}
|
|
62
|
+
if (Anthropic.APIError && error instanceof Anthropic.APIError) {
|
|
63
|
+
return new Error(`Anthropic API error (${error.status}): ${error.message}`);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
catch {
|
|
67
|
+
// instanceof can throw if the RHS is not a valid constructor; fall through
|
|
68
|
+
}
|
|
69
|
+
if (error instanceof Error) {
|
|
70
|
+
return error;
|
|
71
|
+
}
|
|
72
|
+
return new Error(String(error));
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=anthropic-llm-decision.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"anthropic-llm-decision.js","sourceRoot":"","sources":["../../../src/actions/llm-decision/anthropic-llm-decision.ts"],"names":[],"mappings":"AAAA,OAAO,SAAS,MAAM,mBAAmB,CAAC;AAE1C,OAAO,EAAE,sBAAsB,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAOpE,MAAM,aAAa,GAAG,0BAA0B,CAAC;AACjD,MAAM,kBAAkB,GAAG,IAAI,CAAC;AAEhC,MAAM,OAAO,oBAAoB;IACd,MAAM,CAAY;IAClB,YAAY,CAAS;IAEtC,YAAY,OAAqC;QAC/C,MAAM,MAAM,GAAG,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QACpD,IAAI,CAAC,MAAM,GAAG,IAAI,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;QAC7D,IAAI,CAAC,YAAY,GAAG,OAAO,EAAE,YAAY,IAAI,aAAa,CAAC;IAC7D,CAAC;IAED,KAAK,CAAC,MAAM,CAAI,OAA2B;QAEzC,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAEzB,MAAM,WAAW,GAAG,YAAY,OAAO,CAAC,MAAM,mBAAmB,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC;QAE5G,IAAI,QAA2B,CAAC;QAChC,IAAI,CAAC;YACH,QAAQ,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC;gBAC3C,KAAK,EAAE,OAAO,CAAC,KAAK,IAAI,IAAI,CAAC,YAAY;gBACzC,UAAU,EAAE,OAAO,CAAC,SAAS,IAAI,kBAAkB;gBACnD,GAAG,CAAC,OAAO,CAAC,WAAW,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC5E,MAAM,EAAE,aAAa;gBACrB,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,CAAC;gBAClD,KAAK,EAAE;oBACL;wBACE,IAAI,EAAE,kBAAkB;wBACxB,WAAW,EAAE,sCAAsC;wBACnD,YAAY,EAAE,sBAAwD;qBACvE;iBACF;gBACD,WAAW,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,kBAAkB,EAAE;aACxD,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,sBAAsB,CAAC,KAAK,CAAC,CAAC;QACtC,CAAC;QAED,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC;QAErC,MAAM,SAAS,GAAG,QAAQ,CAAC,OAAO,CAAC,IAAI,CACrC,CAAC,KAAK,EAA0D,EAAE,CAChE,KAAK,CAAC,IAAI,KAAK,UAAU,CAC5B,CAAC;QAEF,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,MAAM,IAAI,KAAK,CAAC,gDAAgD,CAAC,CAAC;QACpE,CAAC;QAED,MAAM,QAAQ,GAAG,SAAS,CAAC,KAAU,CAAC;QACtC,MAAM,UAAU,GAAG,QAAQ,CAAC,KAAK,CAAC,YAAY,GAAG,QAAQ,CAAC,KAAK,CAAC,aAAa,CAAC;QAE9E,OAAO;YACL,QAAQ;YACR,WAAW,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,OAAO,CAAC;YAC7C,UAAU;YACV,SAAS;SACV,CAAC;IACJ,CAAC;CACF;AAED,+EAA+E;AAE/E,SAAS,sBAAsB,CAAC,KAAc;IAC5C,IAAI,CAAC;QACH,IAAI,SAAS,CAAC,kBAAkB,IAAI,KAAK,YAAY,SAAS,CAAC,kBAAkB,EAAE,CAAC;YAClF,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC;YAC7F,OAAO,IAAI,KAAK,CAAC,gCAAgC,KAAK,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;QAC7E,CAAC;QACD,IAAI,SAAS,CAAC,mBAAmB,IAAI,KAAK,YAAY,SAAS,CAAC,mBAAmB,EAAE,CAAC;YACpF,OAAO,IAAI,KAAK,CAAC,oCAAoC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;QACxE,CAAC;QACD,IAAI,SAAS,CAAC,QAAQ,IAAI,KAAK,YAAY,SAAS,CAAC,QAAQ,EAAE,CAAC;YAC9D,OAAO,IAAI,KAAK,CAAC,wBAAwB,KAAK,CAAC,MAAM,MAAM,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;QAC9E,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,2EAA2E;IAC7E,CAAC;IACD,IAAI,KAAK,YAAY,KAAK,EAAE,CAAC;QAC3B,OAAO,KAAK,CAAC;IACf,CAAC;IACD,OAAO,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;AAClC,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { LlmDecision } from '../types.js';
|
|
2
|
+
export interface LlmDecisionOptions {
|
|
3
|
+
provider?: 'anthropic' | 'openclaw';
|
|
4
|
+
anthropicApiKey?: string;
|
|
5
|
+
defaultModel?: string;
|
|
6
|
+
gatewayUrl?: string;
|
|
7
|
+
gatewayToken?: string;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Create an LlmDecision client based on the given options.
|
|
11
|
+
*
|
|
12
|
+
* Auto-detection (when `provider` is omitted):
|
|
13
|
+
* - ANTHROPIC_API_KEY env var set → AnthropicLlmDecision
|
|
14
|
+
* - otherwise → OpenClawLlmDecision (uses HTTP gateway)
|
|
15
|
+
*/
|
|
16
|
+
export declare function createLlmDecision(options?: LlmDecisionOptions): LlmDecision;
|
|
17
|
+
//# sourceMappingURL=factory.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../../../src/actions/llm-decision/factory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAI/C,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,EAAE,WAAW,GAAG,UAAU,CAAC;IACpC,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,GAAE,kBAAuB,GAAG,WAAW,CAoB/E"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { AnthropicLlmDecision } from './anthropic-llm-decision.js';
|
|
2
|
+
import { OpenClawLlmDecision } from './openclaw-llm-decision.js';
|
|
3
|
+
/**
|
|
4
|
+
* Create an LlmDecision client based on the given options.
|
|
5
|
+
*
|
|
6
|
+
* Auto-detection (when `provider` is omitted):
|
|
7
|
+
* - ANTHROPIC_API_KEY env var set → AnthropicLlmDecision
|
|
8
|
+
* - otherwise → OpenClawLlmDecision (uses HTTP gateway)
|
|
9
|
+
*/
|
|
10
|
+
export function createLlmDecision(options = {}) {
|
|
11
|
+
const provider = options.provider ??
|
|
12
|
+
(options.anthropicApiKey || process.env.ANTHROPIC_API_KEY ? 'anthropic' : 'openclaw');
|
|
13
|
+
switch (provider) {
|
|
14
|
+
case 'anthropic':
|
|
15
|
+
return new AnthropicLlmDecision({
|
|
16
|
+
apiKey: options.anthropicApiKey,
|
|
17
|
+
defaultModel: options.defaultModel,
|
|
18
|
+
});
|
|
19
|
+
case 'openclaw':
|
|
20
|
+
return new OpenClawLlmDecision({
|
|
21
|
+
gatewayUrl: options.gatewayUrl,
|
|
22
|
+
gatewayToken: options.gatewayToken,
|
|
23
|
+
defaultModel: options.defaultModel,
|
|
24
|
+
});
|
|
25
|
+
default:
|
|
26
|
+
throw new Error(`Unknown LlmDecision provider: ${provider}`);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=factory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"factory.js","sourceRoot":"","sources":["../../../src/actions/llm-decision/factory.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AACnE,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAUjE;;;;;;GAMG;AACH,MAAM,UAAU,iBAAiB,CAAC,UAA8B,EAAE;IAChE,MAAM,QAAQ,GACZ,OAAO,CAAC,QAAQ;QAChB,CAAC,OAAO,CAAC,eAAe,IAAI,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC;IAExF,QAAQ,QAAQ,EAAE,CAAC;QACjB,KAAK,WAAW;YACd,OAAO,IAAI,oBAAoB,CAAC;gBAC9B,MAAM,EAAE,OAAO,CAAC,eAAe;gBAC/B,YAAY,EAAE,OAAO,CAAC,YAAY;aACnC,CAAC,CAAC;QACL,KAAK,UAAU;YACb,OAAO,IAAI,mBAAmB,CAAC;gBAC7B,UAAU,EAAE,OAAO,CAAC,UAAU;gBAC9B,YAAY,EAAE,OAAO,CAAC,YAAY;gBAClC,YAAY,EAAE,OAAO,CAAC,YAAY;aACnC,CAAC,CAAC;QACL;YACE,MAAM,IAAI,KAAK,CAAC,iCAAiC,QAAkB,EAAE,CAAC,CAAC;IAC3E,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export { OpenClawLlmDecision } from './openclaw-llm-decision.js';
|
|
2
|
+
export type { OpenClawLlmDecisionOptions } from './openclaw-llm-decision.js';
|
|
3
|
+
export { AnthropicLlmDecision } from './anthropic-llm-decision.js';
|
|
4
|
+
export type { AnthropicLlmDecisionOptions } from './anthropic-llm-decision.js';
|
|
5
|
+
export { createLlmDecision } from './factory.js';
|
|
6
|
+
export type { LlmDecisionOptions } from './factory.js';
|
|
7
|
+
export { ACTION_DECISION_SCHEMA, SYSTEM_PROMPT, extractDecision, unwrapEnvelope, isRecord, } from './shared.js';
|
|
8
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/actions/llm-decision/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACjE,YAAY,EAAE,0BAA0B,EAAE,MAAM,4BAA4B,CAAC;AAE7E,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AACnE,YAAY,EAAE,2BAA2B,EAAE,MAAM,6BAA6B,CAAC;AAE/E,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACjD,YAAY,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAEvD,OAAO,EACL,sBAAsB,EACtB,aAAa,EACb,eAAe,EACf,cAAc,EACd,QAAQ,GACT,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { OpenClawLlmDecision } from './openclaw-llm-decision.js';
|
|
2
|
+
export { AnthropicLlmDecision } from './anthropic-llm-decision.js';
|
|
3
|
+
export { createLlmDecision } from './factory.js';
|
|
4
|
+
export { ACTION_DECISION_SCHEMA, SYSTEM_PROMPT, extractDecision, unwrapEnvelope, isRecord, } from './shared.js';
|
|
5
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/actions/llm-decision/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAGjE,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AAGnE,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAGjD,OAAO,EACL,sBAAsB,EACtB,aAAa,EACb,eAAe,EACf,cAAc,EACd,QAAQ,GACT,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { LlmDecision, LlmDecisionRequest, LlmDecisionResponse } from '../types.js';
|
|
2
|
+
export interface OpenClawLlmDecisionOptions {
|
|
3
|
+
gatewayUrl?: string;
|
|
4
|
+
gatewayToken?: string;
|
|
5
|
+
defaultModel?: string;
|
|
6
|
+
}
|
|
7
|
+
export declare class OpenClawLlmDecision implements LlmDecision {
|
|
8
|
+
private readonly gatewayUrl;
|
|
9
|
+
private readonly gatewayToken?;
|
|
10
|
+
private readonly defaultModel?;
|
|
11
|
+
constructor(options?: OpenClawLlmDecisionOptions);
|
|
12
|
+
decide<T>(request: LlmDecisionRequest): Promise<LlmDecisionResponse<T>>;
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=openclaw-llm-decision.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openclaw-llm-decision.d.ts","sourceRoot":"","sources":["../../../src/actions/llm-decision/openclaw-llm-decision.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAMxF,MAAM,WAAW,0BAA0B;IACzC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,qBAAa,mBAAoB,YAAW,WAAW;IACrD,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAS;IACvC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAS;gBAE3B,OAAO,CAAC,EAAE,0BAA0B;IAM1C,MAAM,CAAC,CAAC,EAAE,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC;CAkD9E"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { ACTION_DECISION_SCHEMA, SYSTEM_PROMPT, extractDecision } from './shared.js';
|
|
2
|
+
import { createLogger } from '../../utils/logger.js';
|
|
3
|
+
const logger = createLogger('[llm-decision][openclaw]');
|
|
4
|
+
export class OpenClawLlmDecision {
|
|
5
|
+
gatewayUrl;
|
|
6
|
+
gatewayToken;
|
|
7
|
+
defaultModel;
|
|
8
|
+
constructor(options) {
|
|
9
|
+
this.gatewayUrl = options?.gatewayUrl ?? 'http://127.0.0.1:18789';
|
|
10
|
+
this.gatewayToken = options?.gatewayToken;
|
|
11
|
+
this.defaultModel = options?.defaultModel;
|
|
12
|
+
}
|
|
13
|
+
async decide(request) {
|
|
14
|
+
const start = Date.now();
|
|
15
|
+
const token = this.gatewayToken ?? process.env.OPENCLAW_GATEWAY_TOKEN;
|
|
16
|
+
if (!token) {
|
|
17
|
+
throw new Error('OpenClaw gateway token not configured (set OPENCLAW_GATEWAY_TOKEN)');
|
|
18
|
+
}
|
|
19
|
+
const args = {
|
|
20
|
+
prompt: `${SYSTEM_PROMPT}\n\n## Task\n${request.prompt}`,
|
|
21
|
+
input: request.context,
|
|
22
|
+
schema: ACTION_DECISION_SCHEMA,
|
|
23
|
+
};
|
|
24
|
+
const model = request.model ?? this.defaultModel;
|
|
25
|
+
if (model)
|
|
26
|
+
args.model = model;
|
|
27
|
+
if (request.maxTokens != null)
|
|
28
|
+
args.maxTokens = request.maxTokens;
|
|
29
|
+
if (request.temperature != null)
|
|
30
|
+
args.temperature = request.temperature;
|
|
31
|
+
const res = await fetch(`${this.gatewayUrl}/tools/invoke`, {
|
|
32
|
+
method: 'POST',
|
|
33
|
+
headers: {
|
|
34
|
+
'Authorization': `Bearer ${token}`,
|
|
35
|
+
'Content-Type': 'application/json',
|
|
36
|
+
},
|
|
37
|
+
body: JSON.stringify({ tool: 'llm-task', args }),
|
|
38
|
+
});
|
|
39
|
+
if (!res.ok) {
|
|
40
|
+
const text = await res.text();
|
|
41
|
+
throw new Error(`OpenClaw gateway error (${res.status}): ${text}`);
|
|
42
|
+
}
|
|
43
|
+
const body = await res.json();
|
|
44
|
+
if (!body.ok) {
|
|
45
|
+
throw new Error(`OpenClaw gateway rejected request: ${body.error ?? JSON.stringify(body)}`);
|
|
46
|
+
}
|
|
47
|
+
const latencyMs = Date.now() - start;
|
|
48
|
+
logger.debug('llm-task raw result', { keys: body.result && typeof body.result === 'object' ? Object.keys(body.result) : typeof body.result });
|
|
49
|
+
const parsed = extractDecision(body.result);
|
|
50
|
+
return {
|
|
51
|
+
decision: parsed.decision,
|
|
52
|
+
rawResponse: JSON.stringify(body.result),
|
|
53
|
+
tokensUsed: parsed.tokensUsed,
|
|
54
|
+
latencyMs,
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=openclaw-llm-decision.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openclaw-llm-decision.js","sourceRoot":"","sources":["../../../src/actions/llm-decision/openclaw-llm-decision.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
export { isRecord, unwrapEnvelope } from "../../utils/response.js";
|
|
2
|
+
export declare const ACTION_DECISION_SCHEMA: {
|
|
3
|
+
readonly type: "object";
|
|
4
|
+
readonly properties: {
|
|
5
|
+
readonly execute: {
|
|
6
|
+
readonly type: "boolean";
|
|
7
|
+
};
|
|
8
|
+
readonly confidence: {
|
|
9
|
+
readonly type: "integer";
|
|
10
|
+
readonly minimum: 1;
|
|
11
|
+
readonly maximum: 10;
|
|
12
|
+
};
|
|
13
|
+
readonly reasoning: {
|
|
14
|
+
readonly type: "string";
|
|
15
|
+
};
|
|
16
|
+
readonly actionType: {
|
|
17
|
+
readonly type: "string";
|
|
18
|
+
};
|
|
19
|
+
readonly payload: {
|
|
20
|
+
readonly type: "object";
|
|
21
|
+
};
|
|
22
|
+
};
|
|
23
|
+
readonly required: readonly ["execute", "confidence", "reasoning"];
|
|
24
|
+
};
|
|
25
|
+
export declare const SYSTEM_PROMPT = "You are a trading decision engine. Analyze the provided context and decide whether to execute the requested trading action.\n\nRespond with a JSON object:\n- execute (boolean): whether the action should proceed\n- confidence (integer 1\u201310): how confident you are\n- reasoning (string): concise explanation of your decision\n- actionType (string): the action type being evaluated\n- payload (object): action-specific fields as described in the prompt";
|
|
26
|
+
/**
|
|
27
|
+
* Extract a decision object from the llm-task response.
|
|
28
|
+
*
|
|
29
|
+
* Handles multiple response shapes the gateway may return:
|
|
30
|
+
* 1. `{ json: { execute, ... }, usage }` — structured output (preferred)
|
|
31
|
+
* 2. `{ execute, confidence, ... }` — decision at top level
|
|
32
|
+
* 3. `{ details: { json: { execute, ... } }, content }` — gateway /tools/invoke
|
|
33
|
+
* 4. `{ content: [{ type:"text", text:"{ ... }" }] }` — text fallback in content array
|
|
34
|
+
* 5. `{ text: "{ ... }", usage }` — flat text fallback with embedded JSON
|
|
35
|
+
* 6. `{ result: { ... }, usage }` — result-wrapped variant
|
|
36
|
+
*/
|
|
37
|
+
export declare function extractDecision<T>(raw: unknown): {
|
|
38
|
+
decision: T;
|
|
39
|
+
tokensUsed: number;
|
|
40
|
+
};
|
|
41
|
+
//# sourceMappingURL=shared.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../../src/actions/llm-decision/shared.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAEnE,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;;CAUzB,CAAC;AAEX,eAAO,MAAM,aAAa,2cAO4C,CAAC;AA8BvE;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAAC,CAAC,EAAE,GAAG,EAAE,OAAO,GAAG;IAAE,QAAQ,EAAE,CAAC,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CA8DpF"}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
// ─── Constants & helpers shared by all LlmDecision implementations ──────────
|
|
2
|
+
import { isRecord, unwrapEnvelope } from "../../utils/response.js";
|
|
3
|
+
export { isRecord, unwrapEnvelope } from "../../utils/response.js";
|
|
4
|
+
export const ACTION_DECISION_SCHEMA = {
|
|
5
|
+
type: 'object',
|
|
6
|
+
properties: {
|
|
7
|
+
execute: { type: 'boolean' },
|
|
8
|
+
confidence: { type: 'integer', minimum: 1, maximum: 10 },
|
|
9
|
+
reasoning: { type: 'string' },
|
|
10
|
+
actionType: { type: 'string' },
|
|
11
|
+
payload: { type: 'object' },
|
|
12
|
+
},
|
|
13
|
+
required: ['execute', 'confidence', 'reasoning'],
|
|
14
|
+
};
|
|
15
|
+
export const SYSTEM_PROMPT = `You are a trading decision engine. Analyze the provided context and decide whether to execute the requested trading action.
|
|
16
|
+
|
|
17
|
+
Respond with a JSON object:
|
|
18
|
+
- execute (boolean): whether the action should proceed
|
|
19
|
+
- confidence (integer 1–10): how confident you are
|
|
20
|
+
- reasoning (string): concise explanation of your decision
|
|
21
|
+
- actionType (string): the action type being evaluated
|
|
22
|
+
- payload (object): action-specific fields as described in the prompt`;
|
|
23
|
+
// ─── Response parsing ───────────────────────────────────────────────────────
|
|
24
|
+
/**
|
|
25
|
+
* Try to parse a JSON string into a record. Returns null on failure.
|
|
26
|
+
*/
|
|
27
|
+
function tryParseJson(text) {
|
|
28
|
+
try {
|
|
29
|
+
const parsed = JSON.parse(text);
|
|
30
|
+
return isRecord(parsed) ? parsed : null;
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Extract the first text block's content from an OpenClaw `content` array.
|
|
38
|
+
* Shape: `[{ type: "text", text: "..." }, ...]`
|
|
39
|
+
*/
|
|
40
|
+
function extractContentText(content) {
|
|
41
|
+
if (!Array.isArray(content))
|
|
42
|
+
return null;
|
|
43
|
+
for (const block of content) {
|
|
44
|
+
if (isRecord(block) && block.type === 'text' && typeof block.text === 'string') {
|
|
45
|
+
return block.text;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return null;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Extract a decision object from the llm-task response.
|
|
52
|
+
*
|
|
53
|
+
* Handles multiple response shapes the gateway may return:
|
|
54
|
+
* 1. `{ json: { execute, ... }, usage }` — structured output (preferred)
|
|
55
|
+
* 2. `{ execute, confidence, ... }` — decision at top level
|
|
56
|
+
* 3. `{ details: { json: { execute, ... } }, content }` — gateway /tools/invoke
|
|
57
|
+
* 4. `{ content: [{ type:"text", text:"{ ... }" }] }` — text fallback in content array
|
|
58
|
+
* 5. `{ text: "{ ... }", usage }` — flat text fallback with embedded JSON
|
|
59
|
+
* 6. `{ result: { ... }, usage }` — result-wrapped variant
|
|
60
|
+
*/
|
|
61
|
+
export function extractDecision(raw) {
|
|
62
|
+
const data = unwrapEnvelope(raw);
|
|
63
|
+
if (!isRecord(data)) {
|
|
64
|
+
throw new Error('Invalid llm-task response: expected an object');
|
|
65
|
+
}
|
|
66
|
+
let decision;
|
|
67
|
+
// 1. { json: { ... } }
|
|
68
|
+
if ('json' in data && isRecord(data.json)) {
|
|
69
|
+
decision = data.json;
|
|
70
|
+
}
|
|
71
|
+
// 2. flat decision with execute at top level
|
|
72
|
+
else if ('execute' in data) {
|
|
73
|
+
decision = data;
|
|
74
|
+
}
|
|
75
|
+
// 3. { details: { json: { ... } }, content: [...] } — gateway /tools/invoke shape
|
|
76
|
+
else if ('details' in data && isRecord(data.details) && 'json' in data.details && isRecord(data.details.json)) {
|
|
77
|
+
decision = data.details.json;
|
|
78
|
+
}
|
|
79
|
+
// 4. { content: [{ type: "text", text: "{ ... }" }] } — parse JSON from content text block
|
|
80
|
+
else if ('content' in data) {
|
|
81
|
+
const text = extractContentText(data.content);
|
|
82
|
+
if (text) {
|
|
83
|
+
const parsed = tryParseJson(text);
|
|
84
|
+
if (parsed && 'execute' in parsed) {
|
|
85
|
+
decision = parsed;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
// 5. { text: "{ ... }" } — flat text field with embedded JSON
|
|
90
|
+
else if ('text' in data && typeof data.text === 'string') {
|
|
91
|
+
const parsed = tryParseJson(data.text);
|
|
92
|
+
if (parsed && 'execute' in parsed) {
|
|
93
|
+
decision = parsed;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
// 6. { result: { ... } }
|
|
97
|
+
else if ('result' in data && isRecord(data.result)) {
|
|
98
|
+
if ('execute' in data.result) {
|
|
99
|
+
decision = data.result;
|
|
100
|
+
}
|
|
101
|
+
else if ('json' in data.result && isRecord(data.result.json)) {
|
|
102
|
+
decision = data.result.json;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
if (!decision) {
|
|
106
|
+
const keys = Object.keys(data).join(', ');
|
|
107
|
+
throw new Error(`Invalid llm-task response: no decision object found (keys: ${keys})`);
|
|
108
|
+
}
|
|
109
|
+
let tokensUsed = 0;
|
|
110
|
+
if (isRecord(data.usage)) {
|
|
111
|
+
const input = typeof data.usage.inputTokens === 'number' ? data.usage.inputTokens : 0;
|
|
112
|
+
const output = typeof data.usage.outputTokens === 'number' ? data.usage.outputTokens : 0;
|
|
113
|
+
tokensUsed = input + output;
|
|
114
|
+
}
|
|
115
|
+
return { decision: decision, tokensUsed };
|
|
116
|
+
}
|
|
117
|
+
//# sourceMappingURL=shared.js.map
|