@elizaos/plugin-training 2.0.3-beta.6 → 2.0.3-beta.7
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/dist/backends/native.d.ts +96 -0
- package/dist/backends/native.d.ts.map +1 -0
- package/dist/backends/native.js +308 -0
- package/dist/backends/native.js.map +1 -0
- package/dist/cli/train.d.ts +22 -0
- package/dist/cli/train.d.ts.map +1 -0
- package/dist/cli/train.js +219 -0
- package/dist/cli/train.js.map +1 -0
- package/dist/core/action-benchmark-runner.d.ts +55 -0
- package/dist/core/action-benchmark-runner.d.ts.map +1 -0
- package/dist/core/action-benchmark-runner.js +341 -0
- package/dist/core/action-benchmark-runner.js.map +1 -0
- package/dist/core/artifact-store.d.ts +72 -0
- package/dist/core/artifact-store.d.ts.map +1 -0
- package/dist/core/artifact-store.js +50 -0
- package/dist/core/artifact-store.js.map +1 -0
- package/dist/core/benchmark-matrix-artifact.d.ts +102 -0
- package/dist/core/benchmark-matrix-artifact.d.ts.map +1 -0
- package/dist/core/benchmark-matrix-artifact.js +381 -0
- package/dist/core/benchmark-matrix-artifact.js.map +1 -0
- package/dist/core/benchmark-vs-cerebras-runner.d.ts +37 -0
- package/dist/core/benchmark-vs-cerebras-runner.d.ts.map +1 -0
- package/dist/core/benchmark-vs-cerebras-runner.js +151 -0
- package/dist/core/benchmark-vs-cerebras-runner.js.map +1 -0
- package/dist/core/cerebras-eval-model.d.ts +54 -0
- package/dist/core/cerebras-eval-model.d.ts.map +1 -0
- package/dist/core/cerebras-eval-model.js +249 -0
- package/dist/core/cerebras-eval-model.js.map +1 -0
- package/dist/core/cli.d.ts +15 -0
- package/dist/core/cli.d.ts.map +1 -0
- package/dist/core/cli.js +1003 -0
- package/dist/core/cli.js.map +1 -0
- package/dist/core/context-audit.d.ts +51 -0
- package/dist/core/context-audit.d.ts.map +1 -0
- package/dist/core/context-audit.js +166 -0
- package/dist/core/context-audit.js.map +1 -0
- package/dist/core/context-catalog.d.ts +47 -0
- package/dist/core/context-catalog.d.ts.map +1 -0
- package/dist/core/context-catalog.js +269 -0
- package/dist/core/context-catalog.js.map +1 -0
- package/dist/core/context-types.d.ts +3 -0
- package/dist/core/context-types.d.ts.map +1 -0
- package/dist/core/context-types.js +18 -0
- package/dist/core/context-types.js.map +1 -0
- package/dist/core/dataset-generator.d.ts +135 -0
- package/dist/core/dataset-generator.d.ts.map +1 -0
- package/dist/core/dataset-generator.js +895 -0
- package/dist/core/dataset-generator.js.map +1 -0
- package/dist/core/eliza1-benchmark-recipe.d.ts +18 -0
- package/dist/core/eliza1-benchmark-recipe.d.ts.map +1 -0
- package/dist/core/eliza1-benchmark-recipe.js +64 -0
- package/dist/core/eliza1-benchmark-recipe.js.map +1 -0
- package/dist/core/eliza1-bundle-stager.d.ts +57 -0
- package/dist/core/eliza1-bundle-stager.d.ts.map +1 -0
- package/dist/core/eliza1-bundle-stager.js +149 -0
- package/dist/core/eliza1-bundle-stager.js.map +1 -0
- package/dist/core/ensure-cron-job.d.ts +53 -0
- package/dist/core/ensure-cron-job.d.ts.map +1 -0
- package/dist/core/ensure-cron-job.js +51 -0
- package/dist/core/ensure-cron-job.js.map +1 -0
- package/dist/core/eval-comparison-artifact.d.ts +72 -0
- package/dist/core/eval-comparison-artifact.d.ts.map +1 -0
- package/dist/core/eval-comparison-artifact.js +281 -0
- package/dist/core/eval-comparison-artifact.js.map +1 -0
- package/dist/core/feed-generation-runner.d.ts +37 -0
- package/dist/core/feed-generation-runner.d.ts.map +1 -0
- package/dist/core/feed-generation-runner.js +232 -0
- package/dist/core/feed-generation-runner.js.map +1 -0
- package/dist/core/html-escape.d.ts +5 -0
- package/dist/core/html-escape.d.ts.map +1 -0
- package/dist/core/html-escape.js +11 -0
- package/dist/core/html-escape.js.map +1 -0
- package/dist/core/huggingface-dataset-ingest.d.ts +52 -0
- package/dist/core/huggingface-dataset-ingest.d.ts.map +1 -0
- package/dist/core/huggingface-dataset-ingest.js +134 -0
- package/dist/core/huggingface-dataset-ingest.js.map +1 -0
- package/dist/core/index.d.ts +29 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +204 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/privacy-filter.d.ts +95 -0
- package/dist/core/privacy-filter.d.ts.map +1 -0
- package/dist/core/privacy-filter.js +324 -0
- package/dist/core/privacy-filter.js.map +1 -0
- package/dist/core/promotion-gate.d.ts +117 -0
- package/dist/core/promotion-gate.d.ts.map +1 -0
- package/dist/core/promotion-gate.js +85 -0
- package/dist/core/promotion-gate.js.map +1 -0
- package/dist/core/promotion-persist.d.ts +116 -0
- package/dist/core/promotion-persist.d.ts.map +1 -0
- package/dist/core/promotion-persist.js +93 -0
- package/dist/core/promotion-persist.js.map +1 -0
- package/dist/core/prompt-compare.d.ts +99 -0
- package/dist/core/prompt-compare.d.ts.map +1 -0
- package/dist/core/prompt-compare.js +210 -0
- package/dist/core/prompt-compare.js.map +1 -0
- package/dist/core/replay-validator.d.ts +136 -0
- package/dist/core/replay-validator.d.ts.map +1 -0
- package/dist/core/replay-validator.js +312 -0
- package/dist/core/replay-validator.js.map +1 -0
- package/dist/core/roleplay-executor.d.ts +123 -0
- package/dist/core/roleplay-executor.d.ts.map +1 -0
- package/dist/core/roleplay-executor.js +675 -0
- package/dist/core/roleplay-executor.js.map +1 -0
- package/dist/core/roleplay-trajectories.d.ts +54 -0
- package/dist/core/roleplay-trajectories.d.ts.map +1 -0
- package/dist/core/roleplay-trajectories.js +88 -0
- package/dist/core/roleplay-trajectories.js.map +1 -0
- package/dist/core/scenario-blueprints.d.ts +62 -0
- package/dist/core/scenario-blueprints.d.ts.map +1 -0
- package/dist/core/scenario-blueprints.js +850 -0
- package/dist/core/scenario-blueprints.js.map +1 -0
- package/dist/core/scenario-runner.d.ts +36 -0
- package/dist/core/scenario-runner.d.ts.map +1 -0
- package/dist/core/scenario-runner.js +216 -0
- package/dist/core/scenario-runner.js.map +1 -0
- package/dist/core/skill-scoring-cron.d.ts +57 -0
- package/dist/core/skill-scoring-cron.d.ts.map +1 -0
- package/dist/core/skill-scoring-cron.js +180 -0
- package/dist/core/skill-scoring-cron.js.map +1 -0
- package/dist/core/test-trajectory-collector.d.ts +37 -0
- package/dist/core/test-trajectory-collector.d.ts.map +1 -0
- package/dist/core/test-trajectory-collector.js +225 -0
- package/dist/core/test-trajectory-collector.js.map +1 -0
- package/dist/core/track-c-queue-task.d.ts +37 -0
- package/dist/core/track-c-queue-task.d.ts.map +1 -0
- package/dist/core/track-c-queue-task.js +104 -0
- package/dist/core/track-c-queue-task.js.map +1 -0
- package/dist/core/training-analysis-index.d.ts +104 -0
- package/dist/core/training-analysis-index.d.ts.map +1 -0
- package/dist/core/training-analysis-index.js +3297 -0
- package/dist/core/training-analysis-index.js.map +1 -0
- package/dist/core/training-collection-runner.d.ts +508 -0
- package/dist/core/training-collection-runner.d.ts.map +1 -0
- package/dist/core/training-collection-runner.js +2299 -0
- package/dist/core/training-collection-runner.js.map +1 -0
- package/dist/core/training-config.d.ts +52 -0
- package/dist/core/training-config.d.ts.map +1 -0
- package/dist/core/training-config.js +117 -0
- package/dist/core/training-config.js.map +1 -0
- package/dist/core/training-orchestrator.d.ts +112 -0
- package/dist/core/training-orchestrator.d.ts.map +1 -0
- package/dist/core/training-orchestrator.js +729 -0
- package/dist/core/training-orchestrator.js.map +1 -0
- package/dist/core/training-readiness-report.d.ts +52 -0
- package/dist/core/training-readiness-report.d.ts.map +1 -0
- package/dist/core/training-readiness-report.js +765 -0
- package/dist/core/training-readiness-report.js.map +1 -0
- package/dist/core/trajectory-consumer.d.ts +15 -0
- package/dist/core/trajectory-consumer.d.ts.map +1 -0
- package/dist/core/trajectory-consumer.js +61 -0
- package/dist/core/trajectory-consumer.js.map +1 -0
- package/dist/core/trajectory-export-bundle.d.ts +95 -0
- package/dist/core/trajectory-export-bundle.d.ts.map +1 -0
- package/dist/core/trajectory-export-bundle.js +561 -0
- package/dist/core/trajectory-export-bundle.js.map +1 -0
- package/dist/core/trajectory-export-cron.d.ts +57 -0
- package/dist/core/trajectory-export-cron.d.ts.map +1 -0
- package/dist/core/trajectory-export-cron.js +170 -0
- package/dist/core/trajectory-export-cron.js.map +1 -0
- package/dist/core/trajectory-hf-upload.d.ts +50 -0
- package/dist/core/trajectory-hf-upload.d.ts.map +1 -0
- package/dist/core/trajectory-hf-upload.js +111 -0
- package/dist/core/trajectory-hf-upload.js.map +1 -0
- package/dist/core/trajectory-task-datasets.d.ts +62 -0
- package/dist/core/trajectory-task-datasets.d.ts.map +1 -0
- package/dist/core/trajectory-task-datasets.js +427 -0
- package/dist/core/trajectory-task-datasets.js.map +1 -0
- package/dist/core/wait-for-service.d.ts +25 -0
- package/dist/core/wait-for-service.d.ts.map +1 -0
- package/dist/core/wait-for-service.js +19 -0
- package/dist/core/wait-for-service.js.map +1 -0
- package/dist/core/workspace-runtime.d.ts +4 -0
- package/dist/core/workspace-runtime.d.ts.map +1 -0
- package/dist/core/workspace-runtime.js +25 -0
- package/dist/core/workspace-runtime.js.map +1 -0
- package/dist/dspy/artifact.d.ts +54 -0
- package/dist/dspy/artifact.d.ts.map +1 -0
- package/dist/dspy/artifact.js +61 -0
- package/dist/dspy/artifact.js.map +1 -0
- package/dist/dspy/chain-of-thought.d.ts +27 -0
- package/dist/dspy/chain-of-thought.d.ts.map +1 -0
- package/dist/dspy/chain-of-thought.js +43 -0
- package/dist/dspy/chain-of-thought.js.map +1 -0
- package/dist/dspy/examples.d.ts +72 -0
- package/dist/dspy/examples.d.ts.map +1 -0
- package/dist/dspy/examples.js +105 -0
- package/dist/dspy/examples.js.map +1 -0
- package/dist/dspy/index.d.ts +15 -0
- package/dist/dspy/index.d.ts.map +1 -0
- package/dist/dspy/index.js +40 -0
- package/dist/dspy/index.js.map +1 -0
- package/dist/dspy/lm-adapter.d.ts +100 -0
- package/dist/dspy/lm-adapter.d.ts.map +1 -0
- package/dist/dspy/lm-adapter.js +81 -0
- package/dist/dspy/lm-adapter.js.map +1 -0
- package/dist/dspy/optimizers/dspy-bootstrap-fewshot.d.ts +23 -0
- package/dist/dspy/optimizers/dspy-bootstrap-fewshot.d.ts.map +1 -0
- package/dist/dspy/optimizers/dspy-bootstrap-fewshot.js +85 -0
- package/dist/dspy/optimizers/dspy-bootstrap-fewshot.js.map +1 -0
- package/dist/dspy/optimizers/dspy-copro.d.ts +29 -0
- package/dist/dspy/optimizers/dspy-copro.d.ts.map +1 -0
- package/dist/dspy/optimizers/dspy-copro.js +141 -0
- package/dist/dspy/optimizers/dspy-copro.js.map +1 -0
- package/dist/dspy/optimizers/dspy-mipro.d.ts +37 -0
- package/dist/dspy/optimizers/dspy-mipro.d.ts.map +1 -0
- package/dist/dspy/optimizers/dspy-mipro.js +194 -0
- package/dist/dspy/optimizers/dspy-mipro.js.map +1 -0
- package/dist/dspy/optimizers/index.d.ts +5 -0
- package/dist/dspy/optimizers/index.d.ts.map +1 -0
- package/dist/dspy/optimizers/index.js +11 -0
- package/dist/dspy/optimizers/index.js.map +1 -0
- package/dist/dspy/optimizers/types.d.ts +39 -0
- package/dist/dspy/optimizers/types.d.ts.map +1 -0
- package/dist/dspy/optimizers/types.js +1 -0
- package/dist/dspy/optimizers/types.js.map +1 -0
- package/dist/dspy/predict.d.ts +49 -0
- package/dist/dspy/predict.d.ts.map +1 -0
- package/dist/dspy/predict.js +73 -0
- package/dist/dspy/predict.js.map +1 -0
- package/dist/dspy/signature.d.ts +88 -0
- package/dist/dspy/signature.d.ts.map +1 -0
- package/dist/dspy/signature.js +205 -0
- package/dist/dspy/signature.js.map +1 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +15 -0
- package/dist/index.js.map +1 -0
- package/dist/optimizers/bootstrap-fewshot.d.ts +42 -0
- package/dist/optimizers/bootstrap-fewshot.d.ts.map +1 -0
- package/dist/optimizers/bootstrap-fewshot.js +92 -0
- package/dist/optimizers/bootstrap-fewshot.js.map +1 -0
- package/dist/optimizers/gepa.d.ts +63 -0
- package/dist/optimizers/gepa.d.ts.map +1 -0
- package/dist/optimizers/gepa.js +232 -0
- package/dist/optimizers/gepa.js.map +1 -0
- package/dist/optimizers/index.d.ts +7 -0
- package/dist/optimizers/index.d.ts.map +1 -0
- package/dist/optimizers/index.js +51 -0
- package/dist/optimizers/index.js.map +1 -0
- package/dist/optimizers/instruction-search.d.ts +39 -0
- package/dist/optimizers/instruction-search.d.ts.map +1 -0
- package/dist/optimizers/instruction-search.js +108 -0
- package/dist/optimizers/instruction-search.js.map +1 -0
- package/dist/optimizers/prompt-evolution.d.ts +39 -0
- package/dist/optimizers/prompt-evolution.d.ts.map +1 -0
- package/dist/optimizers/prompt-evolution.js +101 -0
- package/dist/optimizers/prompt-evolution.js.map +1 -0
- package/dist/optimizers/scoring.d.ts +139 -0
- package/dist/optimizers/scoring.d.ts.map +1 -0
- package/dist/optimizers/scoring.js +299 -0
- package/dist/optimizers/scoring.js.map +1 -0
- package/dist/optimizers/types.d.ts +105 -0
- package/dist/optimizers/types.d.ts.map +1 -0
- package/dist/optimizers/types.js +1 -0
- package/dist/optimizers/types.js.map +1 -0
- package/dist/register-runtime.d.ts +3 -0
- package/dist/register-runtime.d.ts.map +1 -0
- package/dist/register-runtime.js +60 -0
- package/dist/register-runtime.js.map +1 -0
- package/dist/register-terminal-view.d.ts +15 -0
- package/dist/register-terminal-view.d.ts.map +1 -0
- package/dist/register-terminal-view.js +31 -0
- package/dist/register-terminal-view.js.map +1 -0
- package/dist/routes/experience-routes.d.ts +21 -0
- package/dist/routes/experience-routes.d.ts.map +1 -0
- package/dist/routes/experience-routes.js +513 -0
- package/dist/routes/experience-routes.js.map +1 -0
- package/dist/routes/index.d.ts +5 -0
- package/dist/routes/index.d.ts.map +1 -0
- package/dist/routes/index.js +17 -0
- package/dist/routes/index.js.map +1 -0
- package/dist/routes/training-routes.d.ts +10 -0
- package/dist/routes/training-routes.d.ts.map +1 -0
- package/dist/routes/training-routes.js +1239 -0
- package/dist/routes/training-routes.js.map +1 -0
- package/dist/routes/training-vast-routes.d.ts +35 -0
- package/dist/routes/training-vast-routes.d.ts.map +1 -0
- package/dist/routes/training-vast-routes.js +249 -0
- package/dist/routes/training-vast-routes.js.map +1 -0
- package/dist/routes/trajectory-routes.d.ts +19 -0
- package/dist/routes/trajectory-routes.d.ts.map +1 -0
- package/dist/routes/trajectory-routes.js +1122 -0
- package/dist/routes/trajectory-routes.js.map +1 -0
- package/dist/services/index.d.ts +9 -0
- package/dist/services/index.d.ts.map +1 -0
- package/dist/services/index.js +63 -0
- package/dist/services/index.js.map +1 -0
- package/dist/services/training-backend-check.d.ts +8 -0
- package/dist/services/training-backend-check.d.ts.map +1 -0
- package/dist/services/training-backend-check.js +31 -0
- package/dist/services/training-backend-check.js.map +1 -0
- package/dist/services/training-service-like.d.ts +40 -0
- package/dist/services/training-service-like.d.ts.map +1 -0
- package/dist/services/training-service-like.js +1 -0
- package/dist/services/training-service-like.js.map +1 -0
- package/dist/services/training-service-registry.d.ts +4 -0
- package/dist/services/training-service-registry.d.ts.map +1 -0
- package/dist/services/training-service-registry.js +12 -0
- package/dist/services/training-service-registry.js.map +1 -0
- package/dist/services/training-service.d.ts +59 -0
- package/dist/services/training-service.d.ts.map +1 -0
- package/dist/services/training-service.js +154 -0
- package/dist/services/training-service.js.map +1 -0
- package/dist/services/training-trigger.d.ts +177 -0
- package/dist/services/training-trigger.d.ts.map +1 -0
- package/dist/services/training-trigger.js +300 -0
- package/dist/services/training-trigger.js.map +1 -0
- package/dist/services/training-vast-service.d.ts +149 -0
- package/dist/services/training-vast-service.d.ts.map +1 -0
- package/dist/services/training-vast-service.js +648 -0
- package/dist/services/training-vast-service.js.map +1 -0
- package/dist/services/vast-inference-stats.d.ts +37 -0
- package/dist/services/vast-inference-stats.d.ts.map +1 -0
- package/dist/services/vast-inference-stats.js +81 -0
- package/dist/services/vast-inference-stats.js.map +1 -0
- package/dist/services/vast-job-store.d.ts +74 -0
- package/dist/services/vast-job-store.d.ts.map +1 -0
- package/dist/services/vast-job-store.js +194 -0
- package/dist/services/vast-job-store.js.map +1 -0
- package/dist/services/vast-subprocess.d.ts +27 -0
- package/dist/services/vast-subprocess.d.ts.map +1 -0
- package/dist/services/vast-subprocess.js +78 -0
- package/dist/services/vast-subprocess.js.map +1 -0
- package/dist/setup-routes.d.ts +17 -0
- package/dist/setup-routes.d.ts.map +1 -0
- package/dist/setup-routes.js +319 -0
- package/dist/setup-routes.js.map +1 -0
- package/dist/ui/FineTuningSpatialView.d.ts +49 -0
- package/dist/ui/FineTuningSpatialView.d.ts.map +1 -0
- package/dist/ui/FineTuningSpatialView.js +154 -0
- package/dist/ui/FineTuningSpatialView.js.map +1 -0
- package/dist/ui/FineTuningView.d.ts +7 -0
- package/dist/ui/FineTuningView.d.ts.map +1 -0
- package/dist/ui/FineTuningView.helpers.d.ts +17 -0
- package/dist/ui/FineTuningView.helpers.d.ts.map +1 -0
- package/dist/ui/FineTuningView.helpers.js +30 -0
- package/dist/ui/FineTuningView.helpers.js.map +1 -0
- package/dist/ui/FineTuningView.interact.d.ts +2 -0
- package/dist/ui/FineTuningView.interact.d.ts.map +1 -0
- package/dist/ui/FineTuningView.interact.js +300 -0
- package/dist/ui/FineTuningView.interact.js.map +1 -0
- package/dist/ui/FineTuningView.js +4653 -0
- package/dist/ui/FineTuningView.js.map +1 -0
- package/dist/ui/fine-tuning-panels.d.ts +100 -0
- package/dist/ui/fine-tuning-panels.d.ts.map +1 -0
- package/dist/ui/fine-tuning-panels.helpers.d.ts +19 -0
- package/dist/ui/fine-tuning-panels.helpers.d.ts.map +1 -0
- package/dist/ui/fine-tuning-panels.helpers.js +77 -0
- package/dist/ui/fine-tuning-panels.helpers.js.map +1 -0
- package/dist/ui/fine-tuning-panels.js +928 -0
- package/dist/ui/fine-tuning-panels.js.map +1 -0
- package/dist/ui/index.d.ts +5 -0
- package/dist/ui/index.d.ts.map +1 -0
- package/dist/ui/index.js +5 -0
- package/dist/ui/index.js.map +1 -0
- package/dist/ui/training-view-bundle.d.ts +3 -0
- package/dist/ui/training-view-bundle.d.ts.map +1 -0
- package/dist/ui/training-view-bundle.js +7 -0
- package/dist/ui/training-view-bundle.js.map +1 -0
- package/dist/views/bundle.js +5312 -0
- package/dist/views/bundle.js.map +1 -0
- package/package.json +7 -7
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
import { existsSync, readdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { resolveStateDir } from "@elizaos/core";
|
|
4
|
+
import {
|
|
5
|
+
ensureNamedCronJob,
|
|
6
|
+
registerRuntimeEventOnce
|
|
7
|
+
} from "./ensure-cron-job.js";
|
|
8
|
+
import { scoreSkill } from "./replay-validator.js";
|
|
9
|
+
import { waitForService } from "./wait-for-service.js";
|
|
10
|
+
const SCORE_EVENT_NAME = "TRACK_C_SKILL_SCORE";
|
|
11
|
+
const DEFAULT_TRAJECTORY_LIMIT = 200;
|
|
12
|
+
function curatedActiveDir() {
|
|
13
|
+
return join(resolveStateDir(), "skills", "curated", "active");
|
|
14
|
+
}
|
|
15
|
+
function listCuratedSkillFiles() {
|
|
16
|
+
const dir = curatedActiveDir();
|
|
17
|
+
if (!existsSync(dir)) return [];
|
|
18
|
+
const entries = readdirSync(dir, { withFileTypes: true });
|
|
19
|
+
const out = [];
|
|
20
|
+
for (const entry of entries) {
|
|
21
|
+
if (!entry.isDirectory()) continue;
|
|
22
|
+
if (entry.name.startsWith(".")) continue;
|
|
23
|
+
const file = join(dir, entry.name, "SKILL.md");
|
|
24
|
+
if (existsSync(file)) {
|
|
25
|
+
out.push({ name: entry.name, path: file });
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
return out;
|
|
29
|
+
}
|
|
30
|
+
function applyScoreToSkillFile(filePath, score) {
|
|
31
|
+
const content = readFileSync(filePath, "utf-8");
|
|
32
|
+
const normalized = content.replace(/\r\n/g, "\n");
|
|
33
|
+
if (!normalized.startsWith("---")) return false;
|
|
34
|
+
const endIdx = normalized.indexOf("\n---", 3);
|
|
35
|
+
if (endIdx === -1) return false;
|
|
36
|
+
const yamlBlock = normalized.slice(4, endIdx);
|
|
37
|
+
const tail = normalized.slice(endIdx);
|
|
38
|
+
const lines = yamlBlock.split("\n");
|
|
39
|
+
const provenanceIdx = lines.findIndex(
|
|
40
|
+
(line) => /^provenance:\s*$/.test(line.trimEnd())
|
|
41
|
+
);
|
|
42
|
+
const formattedScore = score.toFixed(4);
|
|
43
|
+
if (provenanceIdx === -1) {
|
|
44
|
+
const created = (/* @__PURE__ */ new Date()).toISOString();
|
|
45
|
+
lines.push(
|
|
46
|
+
"provenance:",
|
|
47
|
+
" source: human",
|
|
48
|
+
` createdAt: ${created}`,
|
|
49
|
+
" refinedCount: 0",
|
|
50
|
+
` lastEvalScore: ${formattedScore}`
|
|
51
|
+
);
|
|
52
|
+
} else {
|
|
53
|
+
let endOfBlock = lines.length;
|
|
54
|
+
for (let i = provenanceIdx + 1; i < lines.length; i++) {
|
|
55
|
+
if (!/^\s/.test(lines[i] ?? "")) {
|
|
56
|
+
endOfBlock = i;
|
|
57
|
+
break;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
let updated = false;
|
|
61
|
+
for (let i = provenanceIdx + 1; i < endOfBlock; i++) {
|
|
62
|
+
const line = lines[i] ?? "";
|
|
63
|
+
if (/^\s+lastEvalScore\s*:/.test(line)) {
|
|
64
|
+
lines[i] = ` lastEvalScore: ${formattedScore}`;
|
|
65
|
+
updated = true;
|
|
66
|
+
break;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
if (!updated) {
|
|
70
|
+
lines.splice(endOfBlock, 0, ` lastEvalScore: ${formattedScore}`);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
const rebuilt = `---
|
|
74
|
+
${lines.join("\n")}${tail}`;
|
|
75
|
+
writeFileSync(filePath, rebuilt, "utf-8");
|
|
76
|
+
return true;
|
|
77
|
+
}
|
|
78
|
+
async function runSkillScoringBatch(runtime, options) {
|
|
79
|
+
const log = runtime.logger ?? {
|
|
80
|
+
info: () => {
|
|
81
|
+
},
|
|
82
|
+
warn: () => {
|
|
83
|
+
},
|
|
84
|
+
error: () => {
|
|
85
|
+
},
|
|
86
|
+
debug: () => {
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
const trajectoryService = runtime.getService(
|
|
90
|
+
"trajectories"
|
|
91
|
+
);
|
|
92
|
+
if (!trajectoryService || typeof trajectoryService.listTrajectories !== "function" || typeof trajectoryService.getTrajectoryDetail !== "function") {
|
|
93
|
+
log.warn("[SkillScoringCron] trajectories service unavailable; skipping");
|
|
94
|
+
return [];
|
|
95
|
+
}
|
|
96
|
+
const limit = options?.trajectoryLimit ?? DEFAULT_TRAJECTORY_LIMIT;
|
|
97
|
+
const list = await trajectoryService.listTrajectories({ limit });
|
|
98
|
+
const trajectories = [];
|
|
99
|
+
for (const item of list.trajectories) {
|
|
100
|
+
const detail = await trajectoryService.getTrajectoryDetail(item.id);
|
|
101
|
+
if (detail) trajectories.push(detail);
|
|
102
|
+
}
|
|
103
|
+
const skills = listCuratedSkillFiles();
|
|
104
|
+
const results = [];
|
|
105
|
+
for (const skill of skills) {
|
|
106
|
+
const score = await scoreSkill({ name: skill.name }, trajectories);
|
|
107
|
+
let updated = false;
|
|
108
|
+
let errorMessage;
|
|
109
|
+
try {
|
|
110
|
+
updated = applyScoreToSkillFile(skill.path, score);
|
|
111
|
+
} catch (err) {
|
|
112
|
+
errorMessage = err instanceof Error ? err.message : String(err);
|
|
113
|
+
log.warn(
|
|
114
|
+
`[SkillScoringCron] failed to update score for "${skill.name}": ${errorMessage}`
|
|
115
|
+
);
|
|
116
|
+
}
|
|
117
|
+
results.push({
|
|
118
|
+
name: skill.name,
|
|
119
|
+
score,
|
|
120
|
+
updated,
|
|
121
|
+
error: errorMessage
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
log.info(
|
|
125
|
+
`[SkillScoringCron] scored ${results.length} curated skills against ${trajectories.length} trajectories`
|
|
126
|
+
);
|
|
127
|
+
return results;
|
|
128
|
+
}
|
|
129
|
+
async function registerSkillScoringCron(runtime, options) {
|
|
130
|
+
const log = runtime.logger ?? {
|
|
131
|
+
info: () => {
|
|
132
|
+
},
|
|
133
|
+
warn: () => {
|
|
134
|
+
},
|
|
135
|
+
error: () => {
|
|
136
|
+
},
|
|
137
|
+
debug: () => {
|
|
138
|
+
}
|
|
139
|
+
};
|
|
140
|
+
const cronService = await waitForService(runtime, "CRON", {
|
|
141
|
+
timeoutMs: 2e3
|
|
142
|
+
});
|
|
143
|
+
if (!cronService || typeof cronService.createJob !== "function") {
|
|
144
|
+
log.debug(
|
|
145
|
+
`[SkillScoringCron] CRON service not registered; cron not scheduled (run on-demand via ${SCORE_EVENT_NAME} event)`
|
|
146
|
+
);
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
registerRuntimeEventOnce(runtime, SCORE_EVENT_NAME, async () => {
|
|
150
|
+
await runSkillScoringBatch(runtime);
|
|
151
|
+
});
|
|
152
|
+
const registration = await ensureNamedCronJob(
|
|
153
|
+
cronService,
|
|
154
|
+
{
|
|
155
|
+
name: "track-c-skill-scoring-nightly",
|
|
156
|
+
description: "Nightly evaluation of curated agent skills",
|
|
157
|
+
enabled: true,
|
|
158
|
+
schedule: {
|
|
159
|
+
kind: "cron",
|
|
160
|
+
expr: options?.schedule ?? "5 3 * * *",
|
|
161
|
+
tz: options?.tz
|
|
162
|
+
},
|
|
163
|
+
payload: {
|
|
164
|
+
kind: "event",
|
|
165
|
+
eventName: SCORE_EVENT_NAME
|
|
166
|
+
},
|
|
167
|
+
metadata: { trackC: true, kind: "skill-scoring" }
|
|
168
|
+
},
|
|
169
|
+
{ log, logPrefix: "[SkillScoringCron]" }
|
|
170
|
+
);
|
|
171
|
+
log.info(
|
|
172
|
+
registration === "created" ? "[SkillScoringCron] registered nightly skill-scoring cron" : "[SkillScoringCron] using existing nightly skill-scoring cron"
|
|
173
|
+
);
|
|
174
|
+
}
|
|
175
|
+
export {
|
|
176
|
+
applyScoreToSkillFile,
|
|
177
|
+
registerSkillScoringCron,
|
|
178
|
+
runSkillScoringBatch
|
|
179
|
+
};
|
|
180
|
+
//# sourceMappingURL=skill-scoring-cron.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/core/skill-scoring-cron.ts"],"sourcesContent":["/**\n * Nightly skill-scoring cron job.\n *\n * For every curated skill (active + disabled), pull the most recent\n * trajectories that referenced the skill, run `scoreSkill`, and rewrite the\n * SKILL.md frontmatter with the new `provenance.lastEvalScore`.\n *\n * The job is registered via the runtime cron/Task scheduling path at agent boot.\n * Failure to compute a score for a single skill never aborts the\n * batch — we surface per-skill errors via the logger and continue.\n */\n\nimport { existsSync, readdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { resolveStateDir } from \"@elizaos/core\";\nimport {\n type CronServiceLike,\n ensureNamedCronJob,\n registerRuntimeEventOnce,\n} from \"./ensure-cron-job.js\";\nimport { type ScoreableTrajectory, scoreSkill } from \"./replay-validator.js\";\nimport { waitForService } from \"./wait-for-service.js\";\n\ninterface MinimalLogger {\n info: (message: string) => void;\n warn: (message: string) => void;\n error: (message: string) => void;\n debug: (message: string) => void;\n}\n\ninterface RuntimeLike {\n getService: (name: string) => unknown;\n logger?: MinimalLogger;\n registerEvent?: (\n name: string,\n handler: (payload: unknown) => Promise<void>,\n ) => void;\n}\n\ninterface TrajectoryServiceLike {\n listTrajectories: (options: {\n limit?: number;\n }) => Promise<{ trajectories: Array<{ id: string }> }>;\n getTrajectoryDetail: (id: string) => Promise<ScoreableTrajectory | null>;\n}\n\nconst SCORE_EVENT_NAME = \"TRACK_C_SKILL_SCORE\";\nconst DEFAULT_TRAJECTORY_LIMIT = 200;\n\nfunction curatedActiveDir(): string {\n return join(resolveStateDir(), \"skills\", \"curated\", \"active\");\n}\n\nfunction listCuratedSkillFiles(): Array<{ name: string; path: string }> {\n const dir = curatedActiveDir();\n if (!existsSync(dir)) return [];\n const entries = readdirSync(dir, { withFileTypes: true });\n const out: Array<{ name: string; path: string }> = [];\n for (const entry of entries) {\n if (!entry.isDirectory()) continue;\n if (entry.name.startsWith(\".\")) continue;\n const file = join(dir, entry.name, \"SKILL.md\");\n if (existsSync(file)) {\n out.push({ name: entry.name, path: file });\n }\n }\n return out;\n}\n\n/**\n * Rewrite a SKILL.md file's `provenance.lastEvalScore` field in place.\n *\n * Implemented as a targeted text replacement to preserve the rest of the\n * frontmatter exactly (no YAML round-trip). Adds `lastEvalScore` to the\n * provenance block when the field is missing.\n */\nexport function applyScoreToSkillFile(\n filePath: string,\n score: number,\n): boolean {\n const content = readFileSync(filePath, \"utf-8\");\n const normalized = content.replace(/\\r\\n/g, \"\\n\");\n if (!normalized.startsWith(\"---\")) return false;\n const endIdx = normalized.indexOf(\"\\n---\", 3);\n if (endIdx === -1) return false;\n const yamlBlock = normalized.slice(4, endIdx);\n const tail = normalized.slice(endIdx);\n const lines = yamlBlock.split(\"\\n\");\n\n const provenanceIdx = lines.findIndex((line) =>\n /^provenance:\\s*$/.test(line.trimEnd()),\n );\n const formattedScore = score.toFixed(4);\n\n if (provenanceIdx === -1) {\n // Append a minimal provenance block.\n const created = new Date().toISOString();\n lines.push(\n \"provenance:\",\n \" source: human\",\n ` createdAt: ${created}`,\n \" refinedCount: 0\",\n ` lastEvalScore: ${formattedScore}`,\n );\n } else {\n let endOfBlock = lines.length;\n for (let i = provenanceIdx + 1; i < lines.length; i++) {\n if (!/^\\s/.test(lines[i] ?? \"\")) {\n endOfBlock = i;\n break;\n }\n }\n let updated = false;\n for (let i = provenanceIdx + 1; i < endOfBlock; i++) {\n const line = lines[i] ?? \"\";\n if (/^\\s+lastEvalScore\\s*:/.test(line)) {\n lines[i] = ` lastEvalScore: ${formattedScore}`;\n updated = true;\n break;\n }\n }\n if (!updated) {\n lines.splice(endOfBlock, 0, ` lastEvalScore: ${formattedScore}`);\n }\n }\n\n const rebuilt = `---\\n${lines.join(\"\\n\")}${tail}`;\n writeFileSync(filePath, rebuilt, \"utf-8\");\n return true;\n}\n\n/**\n * Score every curated active skill against the most recent trajectories from\n * the runtime's trajectory store. Returns a per-skill report (kept small so\n * tests can assert on it).\n */\nexport async function runSkillScoringBatch(\n runtime: RuntimeLike,\n options?: { trajectoryLimit?: number },\n): Promise<\n Array<{ name: string; score: number; updated: boolean; error?: string }>\n> {\n const log: MinimalLogger = runtime.logger ?? {\n info: () => {},\n warn: () => {},\n error: () => {},\n debug: () => {},\n };\n const trajectoryService = runtime.getService(\n \"trajectories\",\n ) as TrajectoryServiceLike | null;\n if (\n !trajectoryService ||\n typeof trajectoryService.listTrajectories !== \"function\" ||\n typeof trajectoryService.getTrajectoryDetail !== \"function\"\n ) {\n log.warn(\"[SkillScoringCron] trajectories service unavailable; skipping\");\n return [];\n }\n\n const limit = options?.trajectoryLimit ?? DEFAULT_TRAJECTORY_LIMIT;\n const list = await trajectoryService.listTrajectories({ limit });\n const trajectories: ScoreableTrajectory[] = [];\n for (const item of list.trajectories) {\n const detail = await trajectoryService.getTrajectoryDetail(item.id);\n if (detail) trajectories.push(detail);\n }\n\n const skills = listCuratedSkillFiles();\n const results: Array<{\n name: string;\n score: number;\n updated: boolean;\n error?: string;\n }> = [];\n for (const skill of skills) {\n const score = await scoreSkill({ name: skill.name }, trajectories);\n let updated = false;\n let errorMessage: string | undefined;\n try {\n updated = applyScoreToSkillFile(skill.path, score);\n } catch (err) {\n errorMessage = err instanceof Error ? err.message : String(err);\n log.warn(\n `[SkillScoringCron] failed to update score for \"${skill.name}\": ${errorMessage}`,\n );\n }\n results.push({\n name: skill.name,\n score,\n updated,\n error: errorMessage,\n });\n }\n log.info(\n `[SkillScoringCron] scored ${results.length} curated skills against ${trajectories.length} trajectories`,\n );\n return results;\n}\n\n/**\n * Register the nightly skill-scoring cron job + event handler against the\n * agent runtime. Safe to call multiple times — we reuse any existing job and\n * prune duplicate persisted registrations by name.\n *\n * Schedule defaults to \"5 3 * * *\" (03:05 local time) so it runs after the\n * trajectory-export cron (which runs at 03:00).\n */\nexport async function registerSkillScoringCron(\n runtime: RuntimeLike,\n options?: { schedule?: string; tz?: string },\n): Promise<void> {\n const log: MinimalLogger = runtime.logger ?? {\n info: () => {},\n warn: () => {},\n error: () => {},\n debug: () => {},\n };\n const cronService = await waitForService<CronServiceLike>(runtime, \"CRON\", {\n timeoutMs: 2_000,\n });\n if (!cronService || typeof cronService.createJob !== \"function\") {\n log.debug(\n `[SkillScoringCron] CRON service not registered; cron not scheduled (run on-demand via ${SCORE_EVENT_NAME} event)`,\n );\n return;\n }\n registerRuntimeEventOnce(runtime, SCORE_EVENT_NAME, async () => {\n await runSkillScoringBatch(runtime);\n });\n const registration = await ensureNamedCronJob(\n cronService,\n {\n name: \"track-c-skill-scoring-nightly\",\n description: \"Nightly evaluation of curated agent skills\",\n enabled: true,\n schedule: {\n kind: \"cron\",\n expr: options?.schedule ?? \"5 3 * * *\",\n tz: options?.tz,\n },\n payload: {\n kind: \"event\",\n eventName: SCORE_EVENT_NAME,\n },\n metadata: { trackC: true, kind: \"skill-scoring\" },\n },\n { log, logPrefix: \"[SkillScoringCron]\" },\n );\n log.info(\n registration === \"created\"\n ? \"[SkillScoringCron] registered nightly skill-scoring cron\"\n : \"[SkillScoringCron] using existing nightly skill-scoring cron\",\n );\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
export declare const TEST_TRAJECTORY_COLLECTION_SCHEMA = "eliza_test_trajectory_collection";
|
|
2
|
+
export declare const TEST_TRAJECTORY_COLLECTION_VERSION = 1;
|
|
3
|
+
export interface CollectTestTrajectoriesOptions {
|
|
4
|
+
roots?: string[];
|
|
5
|
+
outputDir?: string;
|
|
6
|
+
workspaceRoot?: string;
|
|
7
|
+
limit?: number;
|
|
8
|
+
generatedAt?: string;
|
|
9
|
+
syntheticFallback?: boolean;
|
|
10
|
+
}
|
|
11
|
+
export interface CollectedTestTrajectory {
|
|
12
|
+
sourcePath: string;
|
|
13
|
+
outputPath: string;
|
|
14
|
+
caseId?: string;
|
|
15
|
+
scenarioId?: string;
|
|
16
|
+
llmCalls: number;
|
|
17
|
+
actions: number;
|
|
18
|
+
transcriptTurns: number;
|
|
19
|
+
}
|
|
20
|
+
export interface TestTrajectoryCollectionManifest {
|
|
21
|
+
schema: typeof TEST_TRAJECTORY_COLLECTION_SCHEMA;
|
|
22
|
+
schemaVersion: typeof TEST_TRAJECTORY_COLLECTION_VERSION;
|
|
23
|
+
generatedAt: string;
|
|
24
|
+
outputDir: string;
|
|
25
|
+
roots: string[];
|
|
26
|
+
copiedCount: number;
|
|
27
|
+
skippedCount: number;
|
|
28
|
+
syntheticCount?: number;
|
|
29
|
+
copied: CollectedTestTrajectory[];
|
|
30
|
+
}
|
|
31
|
+
export interface TestTrajectoryCollectionResult {
|
|
32
|
+
outputDir: string;
|
|
33
|
+
manifestPath: string;
|
|
34
|
+
manifest: TestTrajectoryCollectionManifest;
|
|
35
|
+
}
|
|
36
|
+
export declare function collectTestTrajectories(options?: CollectTestTrajectoriesOptions): Promise<TestTrajectoryCollectionResult>;
|
|
37
|
+
//# sourceMappingURL=test-trajectory-collector.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"test-trajectory-collector.d.ts","sourceRoot":"","sources":["../../src/core/test-trajectory-collector.ts"],"names":[],"mappings":"AAWA,eAAO,MAAM,iCAAiC,qCACV,CAAC;AACrC,eAAO,MAAM,kCAAkC,IAAI,CAAC;AAEpD,MAAM,WAAW,8BAA8B;IAC7C,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED,MAAM,WAAW,uBAAuB;IACtC,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,gCAAgC;IAC/C,MAAM,EAAE,OAAO,iCAAiC,CAAC;IACjD,aAAa,EAAE,OAAO,kCAAkC,CAAC;IACzD,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,MAAM,EAAE,uBAAuB,EAAE,CAAC;CACnC;AAED,MAAM,WAAW,8BAA8B;IAC7C,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,gCAAgC,CAAC;CAC5C;AAyLD,wBAAsB,uBAAuB,CAC3C,OAAO,GAAE,8BAAmC,GAC3C,OAAO,CAAC,8BAA8B,CAAC,CAsFzC"}
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
import { existsSync } from "node:fs";
|
|
2
|
+
import {
|
|
3
|
+
copyFile,
|
|
4
|
+
mkdir,
|
|
5
|
+
readdir,
|
|
6
|
+
readFile,
|
|
7
|
+
writeFile
|
|
8
|
+
} from "node:fs/promises";
|
|
9
|
+
import { basename, delimiter, join, relative, resolve } from "node:path";
|
|
10
|
+
import { trainingStateRoot } from "./training-config.js";
|
|
11
|
+
const TEST_TRAJECTORY_COLLECTION_SCHEMA = "eliza_test_trajectory_collection";
|
|
12
|
+
const TEST_TRAJECTORY_COLLECTION_VERSION = 1;
|
|
13
|
+
function isRecord(value) {
|
|
14
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
15
|
+
}
|
|
16
|
+
function safeSegment(value) {
|
|
17
|
+
return value.trim().replace(/[/\\:]/g, "-").replace(/[^a-zA-Z0-9._-]+/g, "-").replace(/^-+|-+$/g, "") || "trajectory";
|
|
18
|
+
}
|
|
19
|
+
function looksLikeTestTrajectoryRecord(payload) {
|
|
20
|
+
const agentTrajectory = isRecord(payload.agentTrajectory) ? payload.agentTrajectory : {};
|
|
21
|
+
return (typeof payload.caseId === "string" || typeof payload.scenarioId === "string") && typeof payload.startedAt === "number" && typeof payload.endedAt === "number" && Array.isArray(payload.transcript) && isRecord(payload.agentTrajectory) && Array.isArray(agentTrajectory.llmCalls) && Array.isArray(payload.actions) && Array.isArray(payload.events);
|
|
22
|
+
}
|
|
23
|
+
function envRoots() {
|
|
24
|
+
return [
|
|
25
|
+
process.env.ELIZA_TEST_TRAJECTORY_DIR,
|
|
26
|
+
process.env.ELIZA_ACTION_BENCHMARK_TRAJECTORY_DIR
|
|
27
|
+
].flatMap((value) => value ? value.split(delimiter) : []).map((value) => value.trim()).filter(Boolean);
|
|
28
|
+
}
|
|
29
|
+
function defaultRoots(workspaceRoot) {
|
|
30
|
+
const roots = [...envRoots()];
|
|
31
|
+
if (workspaceRoot) {
|
|
32
|
+
roots.push(
|
|
33
|
+
join(
|
|
34
|
+
workspaceRoot,
|
|
35
|
+
"packages",
|
|
36
|
+
"app-core",
|
|
37
|
+
"test-results",
|
|
38
|
+
"trajectories"
|
|
39
|
+
),
|
|
40
|
+
join(
|
|
41
|
+
workspaceRoot,
|
|
42
|
+
"packages",
|
|
43
|
+
"app-core",
|
|
44
|
+
"test-output",
|
|
45
|
+
"trajectories"
|
|
46
|
+
)
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
return roots.filter((root, index, all) => all.indexOf(root) === index);
|
|
50
|
+
}
|
|
51
|
+
async function collectJsonFiles(root, out) {
|
|
52
|
+
const entries = await readdir(root, { withFileTypes: true });
|
|
53
|
+
for (const entry of entries) {
|
|
54
|
+
if (entry.name === "node_modules" || entry.name === ".git" || entry.name === "dist" || entry.name === "build") {
|
|
55
|
+
continue;
|
|
56
|
+
}
|
|
57
|
+
const path = join(root, entry.name);
|
|
58
|
+
if (entry.isDirectory()) {
|
|
59
|
+
await collectJsonFiles(path, out);
|
|
60
|
+
} else if (entry.isFile() && entry.name.endsWith(".json")) {
|
|
61
|
+
out.push(path);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
async function loadTestTrajectory(path) {
|
|
66
|
+
try {
|
|
67
|
+
const parsed = JSON.parse(await readFile(path, "utf8"));
|
|
68
|
+
return isRecord(parsed) && looksLikeTestTrajectoryRecord(parsed) ? parsed : null;
|
|
69
|
+
} catch {
|
|
70
|
+
return null;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
function summarizeCopied(sourcePath, outputPath, payload) {
|
|
74
|
+
const agentTrajectory = isRecord(payload.agentTrajectory) ? payload.agentTrajectory : {};
|
|
75
|
+
return {
|
|
76
|
+
sourcePath,
|
|
77
|
+
outputPath,
|
|
78
|
+
caseId: typeof payload.caseId === "string" ? payload.caseId : void 0,
|
|
79
|
+
scenarioId: typeof payload.scenarioId === "string" ? payload.scenarioId : void 0,
|
|
80
|
+
llmCalls: Array.isArray(agentTrajectory.llmCalls) ? agentTrajectory.llmCalls.length : 0,
|
|
81
|
+
actions: Array.isArray(payload.actions) ? payload.actions.length : 0,
|
|
82
|
+
transcriptTurns: Array.isArray(payload.transcript) ? payload.transcript.length : 0
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
function syntheticTestTrajectoryRecord(generatedAt) {
|
|
86
|
+
const startedAt = Date.parse(generatedAt);
|
|
87
|
+
const timestamp = Number.isFinite(startedAt) ? startedAt : Date.now();
|
|
88
|
+
const endedAt = timestamp + 1e3;
|
|
89
|
+
return {
|
|
90
|
+
caseId: "dry-run-action-planner",
|
|
91
|
+
scenarioId: "training_collection.synthetic_test",
|
|
92
|
+
startedAt: timestamp,
|
|
93
|
+
endedAt,
|
|
94
|
+
durationMs: endedAt - timestamp,
|
|
95
|
+
transcript: [
|
|
96
|
+
{
|
|
97
|
+
role: "user",
|
|
98
|
+
text: "Can you check my calendar?",
|
|
99
|
+
timestamp
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
role: "assistant",
|
|
103
|
+
text: "I checked the runtime state.",
|
|
104
|
+
actions: ["CHECK_RUNTIME"],
|
|
105
|
+
timestamp: endedAt
|
|
106
|
+
}
|
|
107
|
+
],
|
|
108
|
+
agentTrajectory: {
|
|
109
|
+
llmCalls: [
|
|
110
|
+
{
|
|
111
|
+
callId: "dry-run-action-planner-llm-1",
|
|
112
|
+
timestamp,
|
|
113
|
+
latencyMs: 0,
|
|
114
|
+
modelType: "TEXT_LARGE",
|
|
115
|
+
prompt: "Plan a grounded action for the user request.",
|
|
116
|
+
response: "CHECK_RUNTIME",
|
|
117
|
+
purpose: "action_planner"
|
|
118
|
+
}
|
|
119
|
+
],
|
|
120
|
+
providerSnapshots: []
|
|
121
|
+
},
|
|
122
|
+
actions: [
|
|
123
|
+
{
|
|
124
|
+
phase: "completed",
|
|
125
|
+
actionName: "CHECK_RUNTIME",
|
|
126
|
+
actionStatus: "success",
|
|
127
|
+
timestamp: endedAt
|
|
128
|
+
}
|
|
129
|
+
],
|
|
130
|
+
events: [
|
|
131
|
+
{ type: "RUN_STARTED", timestamp, data: { synthetic: true } },
|
|
132
|
+
{ type: "RUN_ENDED", timestamp: endedAt, data: { synthetic: true } }
|
|
133
|
+
],
|
|
134
|
+
memoriesWritten: [],
|
|
135
|
+
metadata: {
|
|
136
|
+
pass: true,
|
|
137
|
+
dryRun: true,
|
|
138
|
+
synthetic: true,
|
|
139
|
+
tags: ["dry-run", "training-collection"],
|
|
140
|
+
expectedAction: "CHECK_RUNTIME",
|
|
141
|
+
plannedAction: "CHECK_RUNTIME",
|
|
142
|
+
actualAction: "CHECK_RUNTIME"
|
|
143
|
+
}
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
async function collectTestTrajectories(options = {}) {
|
|
147
|
+
const generatedAt = options.generatedAt ?? (/* @__PURE__ */ new Date()).toISOString();
|
|
148
|
+
const outputDir = options.outputDir ?? join(
|
|
149
|
+
trainingStateRoot(),
|
|
150
|
+
"test-trajectories",
|
|
151
|
+
generatedAt.replace(/\D+/g, "-")
|
|
152
|
+
);
|
|
153
|
+
const workspaceRoot = options.workspaceRoot ? resolve(options.workspaceRoot) : void 0;
|
|
154
|
+
const roots = (options.roots?.length ? options.roots : defaultRoots(workspaceRoot)).map((root) => resolve(root)).filter(
|
|
155
|
+
(root, index, all) => existsSync(root) && all.indexOf(root) === index
|
|
156
|
+
);
|
|
157
|
+
const limit = typeof options.limit === "number" && Number.isFinite(options.limit) ? Math.max(1, Math.floor(options.limit)) : 500;
|
|
158
|
+
await mkdir(join(outputDir, "cases"), { recursive: true });
|
|
159
|
+
const candidates = [];
|
|
160
|
+
for (const root of roots) {
|
|
161
|
+
const files = [];
|
|
162
|
+
if (root.endsWith(".json")) {
|
|
163
|
+
files.push(root);
|
|
164
|
+
} else {
|
|
165
|
+
await collectJsonFiles(root, files);
|
|
166
|
+
}
|
|
167
|
+
for (const path of files) {
|
|
168
|
+
candidates.push({ root, path });
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
const copied = [];
|
|
172
|
+
let skippedCount = 0;
|
|
173
|
+
for (const candidate of candidates) {
|
|
174
|
+
if (copied.length >= limit) break;
|
|
175
|
+
const payload = await loadTestTrajectory(candidate.path);
|
|
176
|
+
if (!payload) {
|
|
177
|
+
skippedCount += 1;
|
|
178
|
+
continue;
|
|
179
|
+
}
|
|
180
|
+
const relativeName = safeSegment(
|
|
181
|
+
relative(candidate.root, candidate.path) || basename(candidate.path)
|
|
182
|
+
);
|
|
183
|
+
const outputPath = join(
|
|
184
|
+
outputDir,
|
|
185
|
+
"cases",
|
|
186
|
+
`${String(copied.length + 1).padStart(4, "0")}-${relativeName}`
|
|
187
|
+
);
|
|
188
|
+
await copyFile(candidate.path, outputPath);
|
|
189
|
+
copied.push(summarizeCopied(candidate.path, outputPath, payload));
|
|
190
|
+
}
|
|
191
|
+
let syntheticCount = 0;
|
|
192
|
+
if (copied.length === 0 && roots.length === 0 && options.syntheticFallback) {
|
|
193
|
+
const payload = syntheticTestTrajectoryRecord(generatedAt);
|
|
194
|
+
const outputPath = join(outputDir, "cases", "0001-dry-run-action-planner.json");
|
|
195
|
+
await writeFile(outputPath, `${JSON.stringify(payload, null, 2)}
|
|
196
|
+
`, "utf8");
|
|
197
|
+
copied.push(summarizeCopied(outputPath, outputPath, payload));
|
|
198
|
+
syntheticCount = 1;
|
|
199
|
+
}
|
|
200
|
+
const manifestPath = join(outputDir, "test-trajectory-collection.json");
|
|
201
|
+
const manifest = {
|
|
202
|
+
schema: TEST_TRAJECTORY_COLLECTION_SCHEMA,
|
|
203
|
+
schemaVersion: TEST_TRAJECTORY_COLLECTION_VERSION,
|
|
204
|
+
generatedAt,
|
|
205
|
+
outputDir,
|
|
206
|
+
roots,
|
|
207
|
+
copiedCount: copied.length,
|
|
208
|
+
skippedCount,
|
|
209
|
+
syntheticCount,
|
|
210
|
+
copied
|
|
211
|
+
};
|
|
212
|
+
await writeFile(
|
|
213
|
+
manifestPath,
|
|
214
|
+
`${JSON.stringify(manifest, null, 2)}
|
|
215
|
+
`,
|
|
216
|
+
"utf8"
|
|
217
|
+
);
|
|
218
|
+
return { outputDir, manifestPath, manifest };
|
|
219
|
+
}
|
|
220
|
+
export {
|
|
221
|
+
TEST_TRAJECTORY_COLLECTION_SCHEMA,
|
|
222
|
+
TEST_TRAJECTORY_COLLECTION_VERSION,
|
|
223
|
+
collectTestTrajectories
|
|
224
|
+
};
|
|
225
|
+
//# sourceMappingURL=test-trajectory-collector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/core/test-trajectory-collector.ts"],"sourcesContent":["import { existsSync } from \"node:fs\";\nimport {\n copyFile,\n mkdir,\n readdir,\n readFile,\n writeFile,\n} from \"node:fs/promises\";\nimport { basename, delimiter, join, relative, resolve } from \"node:path\";\nimport { trainingStateRoot } from \"./training-config.js\";\n\nexport const TEST_TRAJECTORY_COLLECTION_SCHEMA =\n \"eliza_test_trajectory_collection\";\nexport const TEST_TRAJECTORY_COLLECTION_VERSION = 1;\n\nexport interface CollectTestTrajectoriesOptions {\n roots?: string[];\n outputDir?: string;\n workspaceRoot?: string;\n limit?: number;\n generatedAt?: string;\n syntheticFallback?: boolean;\n}\n\nexport interface CollectedTestTrajectory {\n sourcePath: string;\n outputPath: string;\n caseId?: string;\n scenarioId?: string;\n llmCalls: number;\n actions: number;\n transcriptTurns: number;\n}\n\nexport interface TestTrajectoryCollectionManifest {\n schema: typeof TEST_TRAJECTORY_COLLECTION_SCHEMA;\n schemaVersion: typeof TEST_TRAJECTORY_COLLECTION_VERSION;\n generatedAt: string;\n outputDir: string;\n roots: string[];\n copiedCount: number;\n skippedCount: number;\n syntheticCount?: number;\n copied: CollectedTestTrajectory[];\n}\n\nexport interface TestTrajectoryCollectionResult {\n outputDir: string;\n manifestPath: string;\n manifest: TestTrajectoryCollectionManifest;\n}\n\ntype JsonRecord = Record<string, unknown>;\n\nfunction isRecord(value: unknown): value is JsonRecord {\n return value !== null && typeof value === \"object\" && !Array.isArray(value);\n}\n\nfunction safeSegment(value: string): string {\n return (\n value\n .trim()\n .replace(/[/\\\\:]/g, \"-\")\n .replace(/[^a-zA-Z0-9._-]+/g, \"-\")\n .replace(/^-+|-+$/g, \"\") || \"trajectory\"\n );\n}\n\nfunction looksLikeTestTrajectoryRecord(payload: JsonRecord): boolean {\n const agentTrajectory = isRecord(payload.agentTrajectory)\n ? payload.agentTrajectory\n : {};\n return (\n (typeof payload.caseId === \"string\" ||\n typeof payload.scenarioId === \"string\") &&\n typeof payload.startedAt === \"number\" &&\n typeof payload.endedAt === \"number\" &&\n Array.isArray(payload.transcript) &&\n isRecord(payload.agentTrajectory) &&\n Array.isArray(agentTrajectory.llmCalls) &&\n Array.isArray(payload.actions) &&\n Array.isArray(payload.events)\n );\n}\n\nfunction envRoots(): string[] {\n return [\n process.env.ELIZA_TEST_TRAJECTORY_DIR,\n process.env.ELIZA_ACTION_BENCHMARK_TRAJECTORY_DIR,\n ]\n .flatMap((value) => (value ? value.split(delimiter) : []))\n .map((value) => value.trim())\n .filter(Boolean);\n}\n\nfunction defaultRoots(workspaceRoot?: string): string[] {\n const roots = [...envRoots()];\n if (workspaceRoot) {\n roots.push(\n join(\n workspaceRoot,\n \"packages\",\n \"app-core\",\n \"test-results\",\n \"trajectories\",\n ),\n join(\n workspaceRoot,\n \"packages\",\n \"app-core\",\n \"test-output\",\n \"trajectories\",\n ),\n );\n }\n return roots.filter((root, index, all) => all.indexOf(root) === index);\n}\n\nasync function collectJsonFiles(root: string, out: string[]): Promise<void> {\n const entries = await readdir(root, { withFileTypes: true });\n for (const entry of entries) {\n if (\n entry.name === \"node_modules\" ||\n entry.name === \".git\" ||\n entry.name === \"dist\" ||\n entry.name === \"build\"\n ) {\n continue;\n }\n const path = join(root, entry.name);\n if (entry.isDirectory()) {\n await collectJsonFiles(path, out);\n } else if (entry.isFile() && entry.name.endsWith(\".json\")) {\n out.push(path);\n }\n }\n}\n\nasync function loadTestTrajectory(path: string): Promise<JsonRecord | null> {\n try {\n const parsed = JSON.parse(await readFile(path, \"utf8\"));\n return isRecord(parsed) && looksLikeTestTrajectoryRecord(parsed)\n ? parsed\n : null;\n } catch {\n return null;\n }\n}\n\nfunction summarizeCopied(\n sourcePath: string,\n outputPath: string,\n payload: JsonRecord,\n): CollectedTestTrajectory {\n const agentTrajectory = isRecord(payload.agentTrajectory)\n ? payload.agentTrajectory\n : {};\n return {\n sourcePath,\n outputPath,\n caseId: typeof payload.caseId === \"string\" ? payload.caseId : undefined,\n scenarioId:\n typeof payload.scenarioId === \"string\" ? payload.scenarioId : undefined,\n llmCalls: Array.isArray(agentTrajectory.llmCalls)\n ? agentTrajectory.llmCalls.length\n : 0,\n actions: Array.isArray(payload.actions) ? payload.actions.length : 0,\n transcriptTurns: Array.isArray(payload.transcript)\n ? payload.transcript.length\n : 0,\n };\n}\n\nfunction syntheticTestTrajectoryRecord(generatedAt: string): JsonRecord {\n const startedAt = Date.parse(generatedAt);\n const timestamp = Number.isFinite(startedAt) ? startedAt : Date.now();\n const endedAt = timestamp + 1_000;\n return {\n caseId: \"dry-run-action-planner\",\n scenarioId: \"training_collection.synthetic_test\",\n startedAt: timestamp,\n endedAt,\n durationMs: endedAt - timestamp,\n transcript: [\n {\n role: \"user\",\n text: \"Can you check my calendar?\",\n timestamp,\n },\n {\n role: \"assistant\",\n text: \"I checked the runtime state.\",\n actions: [\"CHECK_RUNTIME\"],\n timestamp: endedAt,\n },\n ],\n agentTrajectory: {\n llmCalls: [\n {\n callId: \"dry-run-action-planner-llm-1\",\n timestamp,\n latencyMs: 0,\n modelType: \"TEXT_LARGE\",\n prompt: \"Plan a grounded action for the user request.\",\n response: \"CHECK_RUNTIME\",\n purpose: \"action_planner\",\n },\n ],\n providerSnapshots: [],\n },\n actions: [\n {\n phase: \"completed\",\n actionName: \"CHECK_RUNTIME\",\n actionStatus: \"success\",\n timestamp: endedAt,\n },\n ],\n events: [\n { type: \"RUN_STARTED\", timestamp, data: { synthetic: true } },\n { type: \"RUN_ENDED\", timestamp: endedAt, data: { synthetic: true } },\n ],\n memoriesWritten: [],\n metadata: {\n pass: true,\n dryRun: true,\n synthetic: true,\n tags: [\"dry-run\", \"training-collection\"],\n expectedAction: \"CHECK_RUNTIME\",\n plannedAction: \"CHECK_RUNTIME\",\n actualAction: \"CHECK_RUNTIME\",\n },\n };\n}\n\nexport async function collectTestTrajectories(\n options: CollectTestTrajectoriesOptions = {},\n): Promise<TestTrajectoryCollectionResult> {\n const generatedAt = options.generatedAt ?? new Date().toISOString();\n const outputDir =\n options.outputDir ??\n join(\n trainingStateRoot(),\n \"test-trajectories\",\n generatedAt.replace(/\\D+/g, \"-\"),\n );\n const workspaceRoot = options.workspaceRoot\n ? resolve(options.workspaceRoot)\n : undefined;\n const roots = (\n options.roots?.length ? options.roots : defaultRoots(workspaceRoot)\n )\n .map((root) => resolve(root))\n .filter(\n (root, index, all) => existsSync(root) && all.indexOf(root) === index,\n );\n const limit =\n typeof options.limit === \"number\" && Number.isFinite(options.limit)\n ? Math.max(1, Math.floor(options.limit))\n : 500;\n\n await mkdir(join(outputDir, \"cases\"), { recursive: true });\n\n const candidates: Array<{ root: string; path: string }> = [];\n for (const root of roots) {\n const files: string[] = [];\n if (root.endsWith(\".json\")) {\n files.push(root);\n } else {\n await collectJsonFiles(root, files);\n }\n for (const path of files) {\n candidates.push({ root, path });\n }\n }\n\n const copied: CollectedTestTrajectory[] = [];\n let skippedCount = 0;\n for (const candidate of candidates) {\n if (copied.length >= limit) break;\n const payload = await loadTestTrajectory(candidate.path);\n if (!payload) {\n skippedCount += 1;\n continue;\n }\n const relativeName = safeSegment(\n relative(candidate.root, candidate.path) || basename(candidate.path),\n );\n const outputPath = join(\n outputDir,\n \"cases\",\n `${String(copied.length + 1).padStart(4, \"0\")}-${relativeName}`,\n );\n await copyFile(candidate.path, outputPath);\n copied.push(summarizeCopied(candidate.path, outputPath, payload));\n }\n let syntheticCount = 0;\n if (copied.length === 0 && roots.length === 0 && options.syntheticFallback) {\n const payload = syntheticTestTrajectoryRecord(generatedAt);\n const outputPath = join(outputDir, \"cases\", \"0001-dry-run-action-planner.json\");\n await writeFile(outputPath, `${JSON.stringify(payload, null, 2)}\\n`, \"utf8\");\n copied.push(summarizeCopied(outputPath, outputPath, payload));\n syntheticCount = 1;\n }\n\n const manifestPath = join(outputDir, \"test-trajectory-collection.json\");\n const manifest: TestTrajectoryCollectionManifest = {\n schema: TEST_TRAJECTORY_COLLECTION_SCHEMA,\n schemaVersion: TEST_TRAJECTORY_COLLECTION_VERSION,\n generatedAt,\n outputDir,\n roots,\n copiedCount: copied.length,\n skippedCount,\n syntheticCount,\n copied,\n };\n await writeFile(\n manifestPath,\n `${JSON.stringify(manifest, null, 2)}\\n`,\n \"utf8\",\n );\n return { outputDir, manifestPath, manifest };\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Track-C nightly jobs on the elizaOS TaskService repeat-task path (no plugin-cron).
|
|
3
|
+
* Uses the same cron-boundary math as Heartbeats via `computeNextCronRunAtMs`.
|
|
4
|
+
*/
|
|
5
|
+
import type { IAgentRuntime } from "@elizaos/core";
|
|
6
|
+
export declare const TRACK_C_QUEUE_TAGS: readonly ["queue", "repeat", "track-c"];
|
|
7
|
+
export declare const TRACK_C_TRAJECTORY_EXPORT_TASK_NAME: "TRACK_C_TRAJECTORY_EXPORT_NIGHTLY";
|
|
8
|
+
export declare const TRACK_C_SKILL_SCORING_TASK_NAME: "TRACK_C_SKILL_SCORING_NIGHTLY";
|
|
9
|
+
/** Subset of `IAgentRuntime` required for Track-C repeat queue tasks */
|
|
10
|
+
export interface TrackCRuntimeSubset {
|
|
11
|
+
getTaskWorker: IAgentRuntime["getTaskWorker"];
|
|
12
|
+
registerTaskWorker: IAgentRuntime["registerTaskWorker"];
|
|
13
|
+
createTask: IAgentRuntime["createTask"];
|
|
14
|
+
getTasksByName: IAgentRuntime["getTasksByName"];
|
|
15
|
+
deleteTask: IAgentRuntime["deleteTask"];
|
|
16
|
+
}
|
|
17
|
+
interface MinimalLogger {
|
|
18
|
+
info: (message: string) => void;
|
|
19
|
+
warn: (message: string) => void;
|
|
20
|
+
}
|
|
21
|
+
export declare function pruneDuplicateTasksByName(runtime: TrackCRuntimeSubset, taskName: string, log?: Pick<MinimalLogger, "warn">, logPrefix?: string): Promise<void>;
|
|
22
|
+
export interface EnsureTrackCCronRepeatTaskParams {
|
|
23
|
+
taskName: string;
|
|
24
|
+
description: string;
|
|
25
|
+
cronExpr: string;
|
|
26
|
+
timezone?: string;
|
|
27
|
+
log?: MinimalLogger;
|
|
28
|
+
logPrefix?: string;
|
|
29
|
+
onExecute: (rt: IAgentRuntime) => Promise<void>;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Registers a repeat queue task wired to TaskService ticks. Dedupes by task name,
|
|
33
|
+
* invokes `onExecute` on each fire, and sets `nextInterval` from the cron boundary.
|
|
34
|
+
*/
|
|
35
|
+
export declare function ensureTrackCCronRepeatTask(runtime: TrackCRuntimeSubset, params: EnsureTrackCCronRepeatTaskParams): Promise<"created" | "existing">;
|
|
36
|
+
export {};
|
|
37
|
+
//# sourceMappingURL=track-c-queue-task.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"track-c-queue-task.d.ts","sourceRoot":"","sources":["../../src/core/track-c-queue-task.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EAAE,aAAa,EAAQ,MAAM,eAAe,CAAC;AAEzD,eAAO,MAAM,kBAAkB,yCAA0C,CAAC;AAE1E,eAAO,MAAM,mCAAmC,EAC9C,mCAA4C,CAAC;AAC/C,eAAO,MAAM,+BAA+B,EAC1C,+BAAwC,CAAC;AAI3C,wEAAwE;AACxE,MAAM,WAAW,mBAAmB;IAClC,aAAa,EAAE,aAAa,CAAC,eAAe,CAAC,CAAC;IAC9C,kBAAkB,EAAE,aAAa,CAAC,oBAAoB,CAAC,CAAC;IACxD,UAAU,EAAE,aAAa,CAAC,YAAY,CAAC,CAAC;IACxC,cAAc,EAAE,aAAa,CAAC,gBAAgB,CAAC,CAAC;IAChD,UAAU,EAAE,aAAa,CAAC,YAAY,CAAC,CAAC;CACzC;AAED,UAAU,aAAa;IACrB,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAChC,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACjC;AAqBD,wBAAsB,yBAAyB,CAC7C,OAAO,EAAE,mBAAmB,EAC5B,QAAQ,EAAE,MAAM,EAChB,GAAG,CAAC,EAAE,IAAI,CAAC,aAAa,EAAE,MAAM,CAAC,EACjC,SAAS,SAAiB,GACzB,OAAO,CAAC,IAAI,CAAC,CAiBf;AAoCD,MAAM,WAAW,gCAAgC;IAC/C,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,GAAG,CAAC,EAAE,aAAa,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,CAAC,EAAE,EAAE,aAAa,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACjD;AAED;;;GAGG;AACH,wBAAsB,0BAA0B,CAC9C,OAAO,EAAE,mBAAmB,EAC5B,MAAM,EAAE,gCAAgC,GACvC,OAAO,CAAC,SAAS,GAAG,UAAU,CAAC,CAuCjC"}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { computeNextCronRunAtMs } from "@elizaos/agent";
|
|
2
|
+
const TRACK_C_QUEUE_TAGS = ["queue", "repeat", "track-c"];
|
|
3
|
+
const TRACK_C_TRAJECTORY_EXPORT_TASK_NAME = "TRACK_C_TRAJECTORY_EXPORT_NIGHTLY";
|
|
4
|
+
const TRACK_C_SKILL_SCORING_TASK_NAME = "TRACK_C_SKILL_SCORING_NIGHTLY";
|
|
5
|
+
const CRON_FALLBACK_MS = 6e4;
|
|
6
|
+
function taskUpdatedMs(task) {
|
|
7
|
+
const meta = task.metadata;
|
|
8
|
+
if (typeof meta?.updatedAt === "number") return meta.updatedAt;
|
|
9
|
+
if (typeof task.updatedAt === "number") return task.updatedAt;
|
|
10
|
+
if (typeof task.updatedAt === "bigint") return Number(task.updatedAt);
|
|
11
|
+
return 0;
|
|
12
|
+
}
|
|
13
|
+
function msUntilNextCron(expression, timezone) {
|
|
14
|
+
const now = Date.now();
|
|
15
|
+
const next = computeNextCronRunAtMs(expression, now, timezone);
|
|
16
|
+
if (next === null) return CRON_FALLBACK_MS;
|
|
17
|
+
const delta = next - now;
|
|
18
|
+
return delta > 0 ? delta : CRON_FALLBACK_MS;
|
|
19
|
+
}
|
|
20
|
+
async function pruneDuplicateTasksByName(runtime, taskName, log, logPrefix = "[TrackCTask]") {
|
|
21
|
+
const tasks = await runtime.getTasksByName(taskName);
|
|
22
|
+
if (tasks.length <= 1) return;
|
|
23
|
+
const sorted = [...tasks].sort((a, b) => taskUpdatedMs(b) - taskUpdatedMs(a));
|
|
24
|
+
let removed = 0;
|
|
25
|
+
for (const dup of sorted.slice(1)) {
|
|
26
|
+
if (dup.id) {
|
|
27
|
+
await runtime.deleteTask(dup.id);
|
|
28
|
+
removed += 1;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
if (removed > 0) {
|
|
32
|
+
log?.warn(
|
|
33
|
+
`${logPrefix} removed ${removed} duplicate task(s) for "${taskName}"`
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
function registerTrackCWorkerOnce(runtime, taskName, cronExpr, timezone, onExecute) {
|
|
38
|
+
if (runtime.getTaskWorker(taskName)) return;
|
|
39
|
+
runtime.registerTaskWorker({
|
|
40
|
+
name: taskName,
|
|
41
|
+
execute: async (rt, _options, task) => {
|
|
42
|
+
await onExecute(rt);
|
|
43
|
+
const meta = task.metadata ?? {};
|
|
44
|
+
const expr = typeof meta.trackCCronExpr === "string" ? meta.trackCCronExpr : cronExpr;
|
|
45
|
+
const tzRaw = meta.trackCCronTz;
|
|
46
|
+
let tz;
|
|
47
|
+
if (tzRaw === null || tzRaw === void 0) {
|
|
48
|
+
tz = timezone;
|
|
49
|
+
} else if (typeof tzRaw === "string" && tzRaw.length > 0) {
|
|
50
|
+
tz = tzRaw;
|
|
51
|
+
} else {
|
|
52
|
+
tz = timezone;
|
|
53
|
+
}
|
|
54
|
+
return {
|
|
55
|
+
nextInterval: msUntilNextCron(expr, tz)
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
async function ensureTrackCCronRepeatTask(runtime, params) {
|
|
61
|
+
const logPrefix = params.logPrefix ?? "[TrackCTask]";
|
|
62
|
+
await pruneDuplicateTasksByName(
|
|
63
|
+
runtime,
|
|
64
|
+
params.taskName,
|
|
65
|
+
params.log,
|
|
66
|
+
logPrefix
|
|
67
|
+
);
|
|
68
|
+
registerTrackCWorkerOnce(
|
|
69
|
+
runtime,
|
|
70
|
+
params.taskName,
|
|
71
|
+
params.cronExpr,
|
|
72
|
+
params.timezone,
|
|
73
|
+
params.onExecute
|
|
74
|
+
);
|
|
75
|
+
const existing = await runtime.getTasksByName(params.taskName);
|
|
76
|
+
if (existing.length > 0) {
|
|
77
|
+
return "existing";
|
|
78
|
+
}
|
|
79
|
+
const now = Date.now();
|
|
80
|
+
const nextInterval = msUntilNextCron(params.cronExpr, params.timezone);
|
|
81
|
+
await runtime.createTask({
|
|
82
|
+
name: params.taskName,
|
|
83
|
+
description: params.description,
|
|
84
|
+
tags: [...TRACK_C_QUEUE_TAGS],
|
|
85
|
+
metadata: {
|
|
86
|
+
updatedAt: now,
|
|
87
|
+
updateInterval: nextInterval,
|
|
88
|
+
baseInterval: nextInterval,
|
|
89
|
+
maxFailures: -1,
|
|
90
|
+
trackCCronExpr: params.cronExpr,
|
|
91
|
+
trackCCronTz: params.timezone ?? null
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
params.log?.info(`${logPrefix} created repeat task "${params.taskName}"`);
|
|
95
|
+
return "created";
|
|
96
|
+
}
|
|
97
|
+
export {
|
|
98
|
+
TRACK_C_QUEUE_TAGS,
|
|
99
|
+
TRACK_C_SKILL_SCORING_TASK_NAME,
|
|
100
|
+
TRACK_C_TRAJECTORY_EXPORT_TASK_NAME,
|
|
101
|
+
ensureTrackCCronRepeatTask,
|
|
102
|
+
pruneDuplicateTasksByName
|
|
103
|
+
};
|
|
104
|
+
//# sourceMappingURL=track-c-queue-task.js.map
|