agent-insight 0.5.0 → 0.5.2
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/.next/standalone/.next/BUILD_ID +1 -1
- package/.next/standalone/.next/app-path-routes-manifest.json +1 -0
- package/.next/standalone/.next/build-manifest.json +2 -2
- package/.next/standalone/.next/prerender-manifest.json +3 -3
- package/.next/standalone/.next/routes-manifest.json +6 -0
- package/.next/standalone/.next/server/app/(main)/dashboard/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/(main)/eval/trajectory/[taskId]/trace/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/(main)/infra/source/[id]/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/(main)/quality/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/(main)/skill-history/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/(main)/skills/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/(main)/trace/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/_global-error.html +2 -2
- package/.next/standalone/.next/server/app/_global-error.rsc +1 -1
- package/.next/standalone/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_not-found.html +1 -1
- package/.next/standalone/.next/server/app/_not-found.rsc +1 -1
- package/.next/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/accessconfig/channels.html +1 -1
- package/.next/standalone/.next/server/app/accessconfig/channels.rsc +1 -1
- package/.next/standalone/.next/server/app/accessconfig/channels.segments/!KG1haW4p/accessconfig/channels/__PAGE__.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/accessconfig/channels.segments/!KG1haW4p/accessconfig/channels.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/accessconfig/channels.segments/!KG1haW4p/accessconfig.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/accessconfig/channels.segments/!KG1haW4p.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/accessconfig/channels.segments/_full.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/accessconfig/channels.segments/_head.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/accessconfig/channels.segments/_index.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/accessconfig/channels.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/accessconfig/health.html +1 -1
- package/.next/standalone/.next/server/app/accessconfig/health.rsc +1 -1
- package/.next/standalone/.next/server/app/accessconfig/health.segments/!KG1haW4p/accessconfig/health/__PAGE__.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/accessconfig/health.segments/!KG1haW4p/accessconfig/health.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/accessconfig/health.segments/!KG1haW4p/accessconfig.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/accessconfig/health.segments/!KG1haW4p.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/accessconfig/health.segments/_full.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/accessconfig/health.segments/_head.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/accessconfig/health.segments/_index.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/accessconfig/health.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/accessconfig/install.html +2 -2
- package/.next/standalone/.next/server/app/accessconfig/install.rsc +1 -1
- package/.next/standalone/.next/server/app/accessconfig/install.segments/!KG1haW4p/accessconfig/install/__PAGE__.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/accessconfig/install.segments/!KG1haW4p/accessconfig/install.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/accessconfig/install.segments/!KG1haW4p/accessconfig.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/accessconfig/install.segments/!KG1haW4p.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/accessconfig/install.segments/_full.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/accessconfig/install.segments/_head.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/accessconfig/install.segments/_index.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/accessconfig/install.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/accessconfig/webhooks.html +1 -1
- package/.next/standalone/.next/server/app/accessconfig/webhooks.rsc +1 -1
- package/.next/standalone/.next/server/app/accessconfig/webhooks.segments/!KG1haW4p/accessconfig/webhooks/__PAGE__.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/accessconfig/webhooks.segments/!KG1haW4p/accessconfig/webhooks.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/accessconfig/webhooks.segments/!KG1haW4p/accessconfig.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/accessconfig/webhooks.segments/!KG1haW4p.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/accessconfig/webhooks.segments/_full.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/accessconfig/webhooks.segments/_head.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/accessconfig/webhooks.segments/_index.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/accessconfig/webhooks.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/accessconfig.html +1 -1
- package/.next/standalone/.next/server/app/accessconfig.rsc +1 -1
- package/.next/standalone/.next/server/app/accessconfig.segments/!KG1haW4p/accessconfig/__PAGE__.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/accessconfig.segments/!KG1haW4p/accessconfig.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/accessconfig.segments/!KG1haW4p.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/accessconfig.segments/_full.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/accessconfig.segments/_head.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/accessconfig.segments/_index.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/accessconfig.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/agents.html +1 -1
- package/.next/standalone/.next/server/app/agents.rsc +1 -1
- package/.next/standalone/.next/server/app/agents.segments/!KG1haW4p/agents/__PAGE__.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/agents.segments/!KG1haW4p/agents.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/agents.segments/!KG1haW4p.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/agents.segments/_full.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/agents.segments/_head.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/agents.segments/_index.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/agents.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/api/agent/run/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/agent/stream/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/agent-datasets/[id]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/agent-datasets/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/agents/[id]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/agents/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/auth/apikey/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/auth/organization/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/dashboard/stats/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/debug/batch-tasks/[taskId]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/debug/batch-tasks/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/debug/execute/[jobId]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/debug/execute/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/debug/grayscale-tasks/[taskId]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/debug/grayscale-tasks/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/debug/history/[id]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/debug/history/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/eval/config/backfill-routing/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/eval/config/create/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/eval/config/reparse/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/eval/config/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/eval/config/status/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/eval/evaluation/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/eval/rejudge/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/eval/settings/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/eval/settings/test/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/eval/terminate-all/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/eval/trajectory/results/[id]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/eval/trajectory/results/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/eval/trajectory/run/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/eval/trajectory/runs/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/evaluation/[id]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/evaluation/cancel/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/fault/diagnosis/session/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/fault/diagnosis/stream/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/fleet/breakdowns/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/fleet/trends/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/guide/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/ingest/opencode/session-complete/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/ingest/otel/v1/logs/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/ingest/otel/v1/metrics/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/ingest/otel/v1/traces/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/ingest/proxy/[taskId]/[...path]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/ingest/proxy/[taskId]/end/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/ingest/proxy/[taskId]/start/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/ingest/setup/opencode-offline-fix/route/app-paths-manifest.json +3 -0
- package/.next/standalone/.next/server/app/api/ingest/setup/opencode-offline-fix/route/build-manifest.json +11 -0
- package/.next/standalone/.next/server/app/api/ingest/setup/opencode-offline-fix/route/server-reference-manifest.json +4 -0
- package/.next/standalone/.next/server/app/api/ingest/setup/opencode-offline-fix/route.js +7 -0
- package/.next/standalone/.next/server/app/api/ingest/setup/opencode-offline-fix/route.js.map +5 -0
- package/.next/standalone/.next/server/app/api/ingest/setup/opencode-offline-fix/route.js.nft.json +1 -0
- package/.next/standalone/.next/server/app/api/ingest/setup/opencode-offline-fix/route_client-reference-manifest.js +2 -0
- package/.next/standalone/.next/server/app/api/ingest/sync/manifest/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/ingest/sync/opencode/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/ingest/upload/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/observe/data/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/observe/executions/[executionId]/agent-debug/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/observe/executions/[executionId]/agent-debug/skills-analysis/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/observe/executions/[executionId]/analyze-match/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/observe/executions/[executionId]/infra/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/observe/infra/history/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/observe/infra/poll/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/observe/infra/sources/derive/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/observe/infra/sources/overview/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/observe/infra/sources/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/observe/infra/sources/sessions/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/observe/infra/sources/test/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/observe/session/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/observe/task-stats/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/public/otel/v1/traces/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/quality/agents/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/quality/backfill/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/quality/executions/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/quality/report/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/skill-eval/trigger/[skillName]/draft/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/skill-eval/trigger/[skillName]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/skill-eval/trigger/[skillName]/run/[runId]/cancel/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/skill-eval/trigger/[skillName]/run/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/skill-eval/trigger/[skillName]/runs/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/skill-eval/trigger/[skillName]/upload/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/skill-generator/attachments/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/skill-generator/chat/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/skill-generator/download/[sessionId]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/skill-generator/files/content/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/skill-generator/files/download/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/skill-generator/files/info/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/skill-generator/files/list/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/skill-generator/sessions/[id]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/skill-generator/sessions/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/skill-opt/chat/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/skill-opt/plan/items/[id]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/skill-opt/plan/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/skill-opt/sessions/[id]/iterations/[draftNumber]/apply/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/skill-opt/sessions/[id]/iterations/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/skill-opt/sessions/[id]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/skill-opt/sessions/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/skills/[id]/activate/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/skills/[id]/benchmark-generate/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/skills/[id]/runs/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/skills/[id]/toggle/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/skills/[id]/versions/[version]/download/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/skills/[id]/versions/[version]/evaluate/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/skills/[id]/versions/[version]/evaluation-summary/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/skills/[id]/versions/[version]/files/[...path]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/skills/[id]/versions/[version]/parse-flow/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/skills/[id]/versions/[version]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/skills/[id]/versions/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/skills/automation/import/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/skills/automation/push/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/skills/by-name/[name]/analysis-diagnosis/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/skills/by-name/[name]/optimization-points/resolve/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/skills/by-name/[name]/optimization-points/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/skills/by-name/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/skills/logs/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/skills/publish/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/skills/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/skills/sync-enterprise/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/skills/upload/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/user-evaluators/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/dashboard.html +1 -1
- package/.next/standalone/.next/server/app/dashboard.rsc +2 -2
- package/.next/standalone/.next/server/app/dashboard.segments/!KG1haW4p/dashboard/__PAGE__.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/dashboard.segments/!KG1haW4p/dashboard.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/dashboard.segments/!KG1haW4p.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/dashboard.segments/_full.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/dashboard.segments/_head.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/dashboard.segments/_index.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/dashboard.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/dataset.html +1 -1
- package/.next/standalone/.next/server/app/dataset.rsc +1 -1
- package/.next/standalone/.next/server/app/dataset.segments/!KG1haW4p/dataset/__PAGE__.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/dataset.segments/!KG1haW4p/dataset.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/dataset.segments/!KG1haW4p.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/dataset.segments/_full.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/dataset.segments/_head.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/dataset.segments/_index.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/dataset.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/eval/trajectory.html +1 -1
- package/.next/standalone/.next/server/app/eval/trajectory.rsc +1 -1
- package/.next/standalone/.next/server/app/eval/trajectory.segments/!KG1haW4p/eval/trajectory/__PAGE__.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/eval/trajectory.segments/!KG1haW4p/eval/trajectory.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/eval/trajectory.segments/!KG1haW4p/eval.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/eval/trajectory.segments/!KG1haW4p.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/eval/trajectory.segments/_full.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/eval/trajectory.segments/_head.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/eval/trajectory.segments/_index.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/eval/trajectory.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/eval.html +1 -1
- package/.next/standalone/.next/server/app/eval.rsc +1 -1
- package/.next/standalone/.next/server/app/eval.segments/!KG1haW4p/eval/__PAGE__.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/eval.segments/!KG1haW4p/eval.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/eval.segments/!KG1haW4p.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/eval.segments/_full.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/eval.segments/_head.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/eval.segments/_index.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/eval.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/fault.html +1 -1
- package/.next/standalone/.next/server/app/fault.rsc +1 -1
- package/.next/standalone/.next/server/app/fault.segments/!KG1haW4p/fault/__PAGE__.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/fault.segments/!KG1haW4p/fault.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/fault.segments/!KG1haW4p.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/fault.segments/_full.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/fault.segments/_head.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/fault.segments/_index.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/fault.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/index.html +1 -1
- package/.next/standalone/.next/server/app/index.rsc +1 -1
- package/.next/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/infra/sources.html +1 -1
- package/.next/standalone/.next/server/app/infra/sources.rsc +1 -1
- package/.next/standalone/.next/server/app/infra/sources.segments/!KG1haW4p/infra/sources/__PAGE__.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/infra/sources.segments/!KG1haW4p/infra/sources.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/infra/sources.segments/!KG1haW4p/infra.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/infra/sources.segments/!KG1haW4p.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/infra/sources.segments/_full.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/infra/sources.segments/_head.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/infra/sources.segments/_index.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/infra/sources.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/infra.html +1 -1
- package/.next/standalone/.next/server/app/infra.rsc +1 -1
- package/.next/standalone/.next/server/app/infra.segments/!KG1haW4p/infra/__PAGE__.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/infra.segments/!KG1haW4p/infra.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/infra.segments/!KG1haW4p.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/infra.segments/_full.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/infra.segments/_head.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/infra.segments/_index.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/infra.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/login.html +1 -1
- package/.next/standalone/.next/server/app/login.rsc +1 -1
- package/.next/standalone/.next/server/app/login.segments/_full.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/login.segments/_head.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/login.segments/_index.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/login.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/login.segments/login/__PAGE__.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/login.segments/login.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/memory.html +1 -1
- package/.next/standalone/.next/server/app/memory.rsc +1 -1
- package/.next/standalone/.next/server/app/memory.segments/!KG1haW4p/memory/__PAGE__.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/memory.segments/!KG1haW4p/memory.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/memory.segments/!KG1haW4p.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/memory.segments/_full.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/memory.segments/_head.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/memory.segments/_index.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/memory.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/metrics.html +1 -1
- package/.next/standalone/.next/server/app/metrics.rsc +1 -1
- package/.next/standalone/.next/server/app/metrics.segments/!KG1haW4p/metrics/__PAGE__.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/metrics.segments/!KG1haW4p/metrics.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/metrics.segments/!KG1haW4p.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/metrics.segments/_full.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/metrics.segments/_head.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/metrics.segments/_index.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/metrics.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/modelconfig/registry.html +1 -1
- package/.next/standalone/.next/server/app/modelconfig/registry.rsc +1 -1
- package/.next/standalone/.next/server/app/modelconfig/registry.segments/!KG1haW4p/modelconfig/registry/__PAGE__.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/modelconfig/registry.segments/!KG1haW4p/modelconfig/registry.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/modelconfig/registry.segments/!KG1haW4p/modelconfig.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/modelconfig/registry.segments/!KG1haW4p.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/modelconfig/registry.segments/_full.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/modelconfig/registry.segments/_head.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/modelconfig/registry.segments/_index.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/modelconfig/registry.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/modelconfig/web-search.html +1 -1
- package/.next/standalone/.next/server/app/modelconfig/web-search.rsc +1 -1
- package/.next/standalone/.next/server/app/modelconfig/web-search.segments/!KG1haW4p/modelconfig/web-search/__PAGE__.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/modelconfig/web-search.segments/!KG1haW4p/modelconfig/web-search.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/modelconfig/web-search.segments/!KG1haW4p/modelconfig.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/modelconfig/web-search.segments/!KG1haW4p.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/modelconfig/web-search.segments/_full.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/modelconfig/web-search.segments/_head.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/modelconfig/web-search.segments/_index.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/modelconfig/web-search.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/modelconfig.html +1 -1
- package/.next/standalone/.next/server/app/modelconfig.rsc +1 -1
- package/.next/standalone/.next/server/app/modelconfig.segments/!KG1haW4p/modelconfig/__PAGE__.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/modelconfig.segments/!KG1haW4p/modelconfig.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/modelconfig.segments/!KG1haW4p.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/modelconfig.segments/_full.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/modelconfig.segments/_head.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/modelconfig.segments/_index.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/modelconfig.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/optapi.html +1 -1
- package/.next/standalone/.next/server/app/optapi.rsc +1 -1
- package/.next/standalone/.next/server/app/optapi.segments/!KG1haW4p/optapi/__PAGE__.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/optapi.segments/!KG1haW4p/optapi.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/optapi.segments/!KG1haW4p.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/optapi.segments/_full.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/optapi.segments/_head.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/optapi.segments/_index.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/optapi.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/quality.html +1 -1
- package/.next/standalone/.next/server/app/quality.rsc +2 -2
- package/.next/standalone/.next/server/app/quality.segments/!KG1haW4p/quality/__PAGE__.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/quality.segments/!KG1haW4p/quality.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/quality.segments/!KG1haW4p.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/quality.segments/_full.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/quality.segments/_head.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/quality.segments/_index.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/quality.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/security.html +1 -1
- package/.next/standalone/.next/server/app/security.rsc +1 -1
- package/.next/standalone/.next/server/app/security.segments/!KG1haW4p/security/__PAGE__.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/security.segments/!KG1haW4p/security.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/security.segments/!KG1haW4p.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/security.segments/_full.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/security.segments/_head.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/security.segments/_index.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/security.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/skill-detail.html +1 -1
- package/.next/standalone/.next/server/app/skill-detail.rsc +1 -1
- package/.next/standalone/.next/server/app/skill-detail.segments/_full.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/skill-detail.segments/_head.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/skill-detail.segments/_index.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/skill-detail.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/skill-detail.segments/skill-detail/__PAGE__.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/skill-detail.segments/skill-detail.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/skill-eval/grayscale.html +2 -2
- package/.next/standalone/.next/server/app/skill-eval/grayscale.rsc +1 -1
- package/.next/standalone/.next/server/app/skill-eval/grayscale.segments/!KG1haW4p/skill-eval/grayscale/__PAGE__.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/skill-eval/grayscale.segments/!KG1haW4p/skill-eval/grayscale.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/skill-eval/grayscale.segments/!KG1haW4p/skill-eval.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/skill-eval/grayscale.segments/!KG1haW4p.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/skill-eval/grayscale.segments/_full.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/skill-eval/grayscale.segments/_head.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/skill-eval/grayscale.segments/_index.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/skill-eval/grayscale.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/skill-eval.html +1 -1
- package/.next/standalone/.next/server/app/skill-eval.rsc +1 -1
- package/.next/standalone/.next/server/app/skill-eval.segments/!KG1haW4p/skill-eval/__PAGE__.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/skill-eval.segments/!KG1haW4p/skill-eval.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/skill-eval.segments/!KG1haW4p.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/skill-eval.segments/_full.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/skill-eval.segments/_head.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/skill-eval.segments/_index.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/skill-eval.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/skill-generator.html +1 -1
- package/.next/standalone/.next/server/app/skill-generator.rsc +1 -1
- package/.next/standalone/.next/server/app/skill-generator.segments/!KG1haW4p/skill-generator/__PAGE__.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/skill-generator.segments/!KG1haW4p/skill-generator.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/skill-generator.segments/!KG1haW4p.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/skill-generator.segments/_full.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/skill-generator.segments/_head.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/skill-generator.segments/_index.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/skill-generator.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/skill-history.html +1 -1
- package/.next/standalone/.next/server/app/skill-history.rsc +2 -2
- package/.next/standalone/.next/server/app/skill-history.segments/!KG1haW4p/skill-history/__PAGE__.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/skill-history.segments/!KG1haW4p/skill-history.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/skill-history.segments/!KG1haW4p.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/skill-history.segments/_full.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/skill-history.segments/_head.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/skill-history.segments/_index.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/skill-history.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/skill-opt.html +1 -1
- package/.next/standalone/.next/server/app/skill-opt.rsc +1 -1
- package/.next/standalone/.next/server/app/skill-opt.segments/!KG1haW4p/skill-opt/__PAGE__.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/skill-opt.segments/!KG1haW4p/skill-opt.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/skill-opt.segments/!KG1haW4p.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/skill-opt.segments/_full.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/skill-opt.segments/_head.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/skill-opt.segments/_index.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/skill-opt.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/skill-release.html +1 -1
- package/.next/standalone/.next/server/app/skill-release.rsc +1 -1
- package/.next/standalone/.next/server/app/skill-release.segments/!KG1haW4p/skill-release/__PAGE__.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/skill-release.segments/!KG1haW4p/skill-release.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/skill-release.segments/!KG1haW4p.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/skill-release.segments/_full.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/skill-release.segments/_head.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/skill-release.segments/_index.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/skill-release.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/skills.html +1 -1
- package/.next/standalone/.next/server/app/skills.rsc +2 -2
- package/.next/standalone/.next/server/app/skills.segments/!KG1haW4p/skills/__PAGE__.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/skills.segments/!KG1haW4p/skills.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/skills.segments/!KG1haW4p.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/skills.segments/_full.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/skills.segments/_head.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/skills.segments/_index.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/skills.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/trace.html +1 -1
- package/.next/standalone/.next/server/app/trace.rsc +2 -2
- package/.next/standalone/.next/server/app/trace.segments/!KG1haW4p/trace/__PAGE__.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/trace.segments/!KG1haW4p/trace.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/trace.segments/!KG1haW4p.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/trace.segments/_full.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/trace.segments/_head.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/trace.segments/_index.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/trace.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app-paths-manifest.json +1 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__edc6a75f._.js +3 -0
- package/.next/standalone/.next/server/chunks/ce889_server_app_api_ingest_setup_opencode-offline-fix_route_actions_13b9e7e1.js +3 -0
- package/.next/standalone/.next/server/chunks/node_modules_next_dist_esm_build_templates_app-route_c4a195e5.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/_a3d5f9bc._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/node_modules_0ec17dda._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/node_modules_2906b362._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/node_modules_3ad6a908._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/node_modules_6e2c1036._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/node_modules_a443e166._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/node_modules_c49ac16a._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/node_modules_cf1f3d2c._.js +2 -2
- package/.next/standalone/.next/server/pages/404.html +1 -1
- package/.next/standalone/.next/server/pages/500.html +2 -2
- package/.next/standalone/.next/server/server-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/server-reference-manifest.json +1 -1
- package/.next/standalone/.next/static/chunks/1ee0fbf466669cb8.js +1 -0
- package/.next/standalone/.next/static/chunks/3a0f454536f3ebc8.js +1 -0
- package/.next/standalone/.next/static/chunks/4dcd21eef469e66b.js +1 -0
- package/.next/{static/chunks/7e6eb6ade82c4979.js → standalone/.next/static/chunks/b40cbbf52dfd5473.js} +1 -1
- package/.next/standalone/.next/static/chunks/ec50621fcfea9f71.js +287 -0
- package/.next/standalone/Dockerfile +10 -2
- package/.next/standalone/Evaluation_and_Research/agent_evaluator_industry_research.md +260 -0
- package/.next/standalone/Evaluation_and_Research/agent_evaluator_research_qna.md +1379 -0
- package/.next/standalone/Evaluation_and_Research/agent_evaluator_research_qna_2.md +1312 -0
- package/.next/standalone/Evaluation_and_Research/agent_evaluator_research_qna_3.md +712 -0
- package/.next/standalone/Evaluation_and_Research/agent_evaluator_research_qna_4.md +1228 -0
- package/.next/standalone/docker-compose.amd64.yml +10 -0
- package/.next/standalone/package.json +1 -1
- package/.next/standalone/scripts/opencode-offline-fix.ps1 +93 -0
- package/.next/standalone/scripts/opencode_tui_plugin.tsx +23 -1
- package/.next/static/chunks/1ee0fbf466669cb8.js +1 -0
- package/.next/static/chunks/3a0f454536f3ebc8.js +1 -0
- package/.next/static/chunks/4dcd21eef469e66b.js +1 -0
- package/.next/{standalone/.next/static/chunks/7e6eb6ade82c4979.js → static/chunks/b40cbbf52dfd5473.js} +1 -1
- package/.next/static/chunks/ec50621fcfea9f71.js +287 -0
- package/README.md +76 -60
- package/package.json +1 -1
- package/scripts/opencode-offline-fix.ps1 +93 -0
- package/scripts/opencode_tui_plugin.tsx +23 -1
- package/.next/standalone/.next/static/chunks/13ea6fabf1d0af65.js +0 -287
- package/.next/standalone/.next/static/chunks/74a2b1d10a1772b4.js +0 -1
- package/.next/standalone/.next/static/chunks/94042ce1cf94ccfd.js +0 -1
- package/.next/standalone/.next/static/chunks/965c5a1f38c3d7db.js +0 -1
- package/.next/standalone/scripts/activate_telemetry.sh +0 -202
- package/.next/standalone/scripts/insight-paths.js +0 -33
- package/.next/standalone/scripts/opencode_otel_schema.ts +0 -73
- package/.next/standalone/scripts/opencode_plugin.ts +0 -1063
- package/.next/static/chunks/13ea6fabf1d0af65.js +0 -287
- package/.next/static/chunks/74a2b1d10a1772b4.js +0 -1
- package/.next/static/chunks/94042ce1cf94ccfd.js +0 -1
- package/.next/static/chunks/965c5a1f38c3d7db.js +0 -1
- package/scripts/activate_telemetry.sh +0 -202
- package/scripts/insight-paths.js +0 -33
- package/scripts/opencode_otel_schema.ts +0 -73
- package/scripts/opencode_plugin.ts +0 -1063
- /package/.next/standalone/.next/static/{uwRBb8F1kIm0K4LV3Jkwa → iE8084jR9Kgb7Bhs3Xokh}/_buildManifest.js +0 -0
- /package/.next/standalone/.next/static/{uwRBb8F1kIm0K4LV3Jkwa → iE8084jR9Kgb7Bhs3Xokh}/_clientMiddlewareManifest.json +0 -0
- /package/.next/standalone/.next/static/{uwRBb8F1kIm0K4LV3Jkwa → iE8084jR9Kgb7Bhs3Xokh}/_ssgManifest.js +0 -0
- /package/.next/static/{uwRBb8F1kIm0K4LV3Jkwa → iE8084jR9Kgb7Bhs3Xokh}/_buildManifest.js +0 -0
- /package/.next/static/{uwRBb8F1kIm0K4LV3Jkwa → iE8084jR9Kgb7Bhs3Xokh}/_clientMiddlewareManifest.json +0 -0
- /package/.next/static/{uwRBb8F1kIm0K4LV3Jkwa → iE8084jR9Kgb7Bhs3Xokh}/_ssgManifest.js +0 -0
|
@@ -1,1063 +0,0 @@
|
|
|
1
|
-
// @ts-nocheck
|
|
2
|
-
const http = require('http');
|
|
3
|
-
const https = require('https');
|
|
4
|
-
const fs = require('fs');
|
|
5
|
-
const path = require('path');
|
|
6
|
-
const os = require('os');
|
|
7
|
-
const { URL } = require('url');
|
|
8
|
-
|
|
9
|
-
const DEBUG_LOG = path.join(os.homedir(), '.opencode', 'witty_plugin_debug.log');
|
|
10
|
-
|
|
11
|
-
function logDebug(msg) {
|
|
12
|
-
try {
|
|
13
|
-
const logDir = path.dirname(DEBUG_LOG);
|
|
14
|
-
if (!fs.existsSync(logDir)) fs.mkdirSync(logDir, { recursive: true });
|
|
15
|
-
fs.appendFileSync(DEBUG_LOG, new Date().toISOString() + ' ' + msg + '\n');
|
|
16
|
-
} catch (e) {}
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
// Global store
|
|
20
|
-
let sessionStore = new Map();
|
|
21
|
-
let uploadedSessions = new Map(); // sessionId -> uploaded message count
|
|
22
|
-
let sessionGraph = new Map(); // parent_id -> [child_ids]
|
|
23
|
-
let pendingChildSessions = new Map(); // child_id -> {parent_id, data}
|
|
24
|
-
let lastDeltaByPartField = new Map();
|
|
25
|
-
let sessionParentById = new Map();
|
|
26
|
-
let sessionAgentById = new Map();
|
|
27
|
-
let subagentTypeBySessionId = new Map();
|
|
28
|
-
let eagerFlushMsgIds = new Set();
|
|
29
|
-
let lastEagerFlushAtBySessionId = new Map();
|
|
30
|
-
|
|
31
|
-
const STORE_PATH = path.join(os.homedir(), '.opencode', 'witty_plugin_session_store.json');
|
|
32
|
-
|
|
33
|
-
function cleanupOldSessions() {
|
|
34
|
-
const now = Date.now();
|
|
35
|
-
const threeDays = 3 * 24 * 3600 * 1000;
|
|
36
|
-
|
|
37
|
-
let deletedCount = 0;
|
|
38
|
-
for (const [msgId, entry] of sessionStore.entries()) {
|
|
39
|
-
const time = entry.info?.created || entry.info?.time?.created;
|
|
40
|
-
if (time && (now - time > threeDays)) {
|
|
41
|
-
sessionStore.delete(msgId);
|
|
42
|
-
deletedCount++;
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
if (deletedCount > 0) logDebug(`Cleaned up ${deletedCount} old messages from sessionStore`);
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
function loadStore() {
|
|
49
|
-
try {
|
|
50
|
-
if (fs.existsSync(STORE_PATH)) {
|
|
51
|
-
const fileData = fs.readFileSync(STORE_PATH, 'utf8');
|
|
52
|
-
if (!fileData.trim()) return;
|
|
53
|
-
const data = JSON.parse(fileData);
|
|
54
|
-
|
|
55
|
-
// Merge sessionStore: disk entries fill in gaps, but don't overwrite in-memory entries
|
|
56
|
-
if (data.sessionStore) {
|
|
57
|
-
const diskStore = new Map(data.sessionStore);
|
|
58
|
-
for (const [msgId, entry] of diskStore.entries()) {
|
|
59
|
-
if (!sessionStore.has(msgId)) {
|
|
60
|
-
if (entry.parts && !Array.isArray(entry.parts) && typeof entry.parts === 'object' && !(entry.parts instanceof Map)) {
|
|
61
|
-
entry.parts = new Map(Object.entries(entry.parts));
|
|
62
|
-
} else if (Array.isArray(entry.parts)) {
|
|
63
|
-
entry.parts = new Map(entry.parts);
|
|
64
|
-
} else if (!entry.parts) {
|
|
65
|
-
entry.parts = new Map();
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
if (entry.toolParts && !Array.isArray(entry.toolParts) && typeof entry.toolParts === 'object' && !(entry.toolParts instanceof Map)) {
|
|
69
|
-
entry.toolParts = new Map(Object.entries(entry.toolParts));
|
|
70
|
-
} else if (Array.isArray(entry.toolParts)) {
|
|
71
|
-
entry.toolParts = new Map(entry.toolParts);
|
|
72
|
-
} else if (!entry.toolParts) {
|
|
73
|
-
entry.toolParts = new Map();
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
sessionStore.set(msgId, entry);
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
// Merge uploadedSessions: keep the "newer" signature between memory and disk
|
|
82
|
-
if (data.uploadedSessions) {
|
|
83
|
-
for (const x of data.uploadedSessions) {
|
|
84
|
-
const sid = Array.isArray(x) ? x[0] : x;
|
|
85
|
-
const diskVal = Array.isArray(x) ? x[1] : 0;
|
|
86
|
-
|
|
87
|
-
const normalize = (v) => {
|
|
88
|
-
if (typeof v === 'number') return { count: v, lastAssistantLen: 0, lastTs: 0 };
|
|
89
|
-
if (v && typeof v === 'object') {
|
|
90
|
-
return {
|
|
91
|
-
count: Number(v.count || 0),
|
|
92
|
-
lastAssistantLen: Number(v.lastAssistantLen || 0),
|
|
93
|
-
lastTs: Number(v.lastTs || 0)
|
|
94
|
-
};
|
|
95
|
-
}
|
|
96
|
-
return { count: 0, lastAssistantLen: 0, lastTs: 0 };
|
|
97
|
-
};
|
|
98
|
-
|
|
99
|
-
const memSig = normalize(uploadedSessions.get(sid));
|
|
100
|
-
const diskSig = normalize(diskVal);
|
|
101
|
-
|
|
102
|
-
const diskNewer =
|
|
103
|
-
diskSig.count > memSig.count ||
|
|
104
|
-
(diskSig.count === memSig.count && diskSig.lastAssistantLen > memSig.lastAssistantLen) ||
|
|
105
|
-
(diskSig.count === memSig.count && diskSig.lastAssistantLen === memSig.lastAssistantLen && diskSig.lastTs > memSig.lastTs);
|
|
106
|
-
|
|
107
|
-
if (diskNewer) {
|
|
108
|
-
uploadedSessions.set(sid, diskVal);
|
|
109
|
-
} else if (!uploadedSessions.has(sid)) {
|
|
110
|
-
uploadedSessions.set(sid, memSig);
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
// Merge sessionGraph: union child lists
|
|
116
|
-
if (data.sessionGraph) {
|
|
117
|
-
const diskGraph = new Map(data.sessionGraph);
|
|
118
|
-
for (const [parentId, childIds] of diskGraph.entries()) {
|
|
119
|
-
if (!sessionGraph.has(parentId)) {
|
|
120
|
-
sessionGraph.set(parentId, childIds);
|
|
121
|
-
} else {
|
|
122
|
-
const existing = sessionGraph.get(parentId);
|
|
123
|
-
for (const cid of childIds) {
|
|
124
|
-
if (!existing.includes(cid)) existing.push(cid);
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
// Merge pendingChildSessions
|
|
131
|
-
if (data.pendingChildSessions) {
|
|
132
|
-
const diskPending = new Map(data.pendingChildSessions);
|
|
133
|
-
for (const [childId, childData] of diskPending.entries()) {
|
|
134
|
-
if (!pendingChildSessions.has(childId)) {
|
|
135
|
-
pendingChildSessions.set(childId, childData);
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
if (data.sessionParentById) {
|
|
141
|
-
const diskParents = new Map(data.sessionParentById);
|
|
142
|
-
for (const [sid, pid] of diskParents.entries()) {
|
|
143
|
-
if (!sessionParentById.has(sid) && pid) sessionParentById.set(sid, pid);
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
if (data.sessionAgentById) {
|
|
148
|
-
const diskAgents = new Map(data.sessionAgentById);
|
|
149
|
-
for (const [sid, agentName] of diskAgents.entries()) {
|
|
150
|
-
if (!sessionAgentById.has(sid) && agentName) sessionAgentById.set(sid, agentName);
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
if (data.subagentTypeBySessionId) {
|
|
155
|
-
const diskTypes = new Map(data.subagentTypeBySessionId);
|
|
156
|
-
for (const [sid, t] of diskTypes.entries()) {
|
|
157
|
-
if (!subagentTypeBySessionId.has(sid) && t) subagentTypeBySessionId.set(sid, t);
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
logDebug(`Loaded store (merged): ${sessionStore.size} messages`);
|
|
162
|
-
}
|
|
163
|
-
} catch(e) {
|
|
164
|
-
logDebug("Store read err: " + e.message);
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
function saveStore() {
|
|
169
|
-
try {
|
|
170
|
-
cleanupOldSessions();
|
|
171
|
-
|
|
172
|
-
// Merge with disk state to prevent concurrent process data loss.
|
|
173
|
-
// loadStore() uses merge semantics (won't overwrite in-memory entries).
|
|
174
|
-
loadStore();
|
|
175
|
-
|
|
176
|
-
const data = {
|
|
177
|
-
sessionStore: Array.from(sessionStore.entries()).map(([k, v]) => [k, {
|
|
178
|
-
...v,
|
|
179
|
-
parts: v.parts instanceof Map ? Array.from(v.parts.entries()) : (v.parts || []),
|
|
180
|
-
toolParts: v.toolParts instanceof Map ? Array.from(v.toolParts.entries()) : (v.toolParts || [])
|
|
181
|
-
}]),
|
|
182
|
-
uploadedSessions: Array.from(uploadedSessions.entries()),
|
|
183
|
-
sessionGraph: Array.from(sessionGraph.entries()),
|
|
184
|
-
pendingChildSessions: Array.from(pendingChildSessions.entries()),
|
|
185
|
-
sessionParentById: Array.from(sessionParentById.entries()),
|
|
186
|
-
sessionAgentById: Array.from(sessionAgentById.entries()),
|
|
187
|
-
subagentTypeBySessionId: Array.from(subagentTypeBySessionId.entries()),
|
|
188
|
-
timestamp: new Date().toISOString()
|
|
189
|
-
};
|
|
190
|
-
fs.writeFileSync(STORE_PATH, JSON.stringify(data, null, 2), 'utf8');
|
|
191
|
-
} catch(e) {
|
|
192
|
-
logDebug("Store sync err: " + e.message);
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
function toMsTimestamp(v) {
|
|
197
|
-
if (v == null) return null;
|
|
198
|
-
if (typeof v === 'number' && Number.isFinite(v)) return v;
|
|
199
|
-
if (typeof v === 'string') {
|
|
200
|
-
const s = v.trim();
|
|
201
|
-
if (!s) return null;
|
|
202
|
-
// numeric string (ms)
|
|
203
|
-
if (/^\d+$/.test(s)) {
|
|
204
|
-
const n = Number(s);
|
|
205
|
-
return Number.isFinite(n) ? n : null;
|
|
206
|
-
}
|
|
207
|
-
// ISO-like
|
|
208
|
-
const t = Date.parse(s);
|
|
209
|
-
return Number.isFinite(t) ? t : null;
|
|
210
|
-
}
|
|
211
|
-
return null;
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
function buildTiming(startRaw, endRaw) {
|
|
215
|
-
const startMs = toMsTimestamp(startRaw);
|
|
216
|
-
const endMs = toMsTimestamp(endRaw);
|
|
217
|
-
let durationMs = null;
|
|
218
|
-
if (startMs != null && endMs != null) {
|
|
219
|
-
const d = endMs - startMs;
|
|
220
|
-
// guard against bogus clocks/units: ignore >= 1h spans for tool call
|
|
221
|
-
if (d >= 0 && d < 3600000) durationMs = d;
|
|
222
|
-
}
|
|
223
|
-
// Only attach timing if we have at least one bound
|
|
224
|
-
if (startRaw == null && endRaw == null) return undefined;
|
|
225
|
-
const timing = {};
|
|
226
|
-
if (startRaw != null) timing.started_at = startRaw;
|
|
227
|
-
if (endRaw != null) timing.completed_at = endRaw;
|
|
228
|
-
if (durationMs != null) timing.duration_ms = durationMs;
|
|
229
|
-
return timing;
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
// Helper: Check if host should skip proxy based on NO_PROXY
|
|
233
|
-
function shouldSkipProxy(targetHostname) {
|
|
234
|
-
const noProxy = process.env.no_proxy || process.env.NO_PROXY;
|
|
235
|
-
if (!noProxy) return false;
|
|
236
|
-
const segments = noProxy.split(',').map(s => s.trim().toLowerCase());
|
|
237
|
-
return segments.some(s => s === '*' || targetHostname.toLowerCase().endsWith(s));
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
// Helper: Get proxy setup
|
|
241
|
-
function getRequestOptions(targetUrl, apiKey, bodyLength) {
|
|
242
|
-
const protocol = targetUrl.protocol;
|
|
243
|
-
const proxy = (protocol === 'https:' ? (process.env.https_proxy || process.env.HTTPS_PROXY) : (process.env.http_proxy || process.env.HTTP_PROXY)) || process.env.all_proxy || process.env.ALL_PROXY;
|
|
244
|
-
|
|
245
|
-
let options = {
|
|
246
|
-
hostname: targetUrl.hostname,
|
|
247
|
-
port: targetUrl.port || (protocol === 'https:' ? 443 : 80),
|
|
248
|
-
path: (targetUrl.pathname === '/' ? '' : targetUrl.pathname) + '/api/upload',
|
|
249
|
-
method: 'POST',
|
|
250
|
-
headers: {
|
|
251
|
-
'Content-Type': 'application/json',
|
|
252
|
-
'Content-Length': bodyLength,
|
|
253
|
-
'x-witty-api-key': apiKey
|
|
254
|
-
}
|
|
255
|
-
};
|
|
256
|
-
|
|
257
|
-
if (proxy && !shouldSkipProxy(targetUrl.hostname)) {
|
|
258
|
-
try {
|
|
259
|
-
const proxyUrl = new URL(proxy);
|
|
260
|
-
if (protocol === 'http:') {
|
|
261
|
-
options.hostname = proxyUrl.hostname;
|
|
262
|
-
options.port = proxyUrl.port || 80;
|
|
263
|
-
options.path = targetUrl.origin + options.path;
|
|
264
|
-
if (proxyUrl.username) {
|
|
265
|
-
const auth = Buffer.from(`${proxyUrl.username}:${proxyUrl.password}`).toString('base64');
|
|
266
|
-
options.headers['Proxy-Authorization'] = `Basic ${auth}`;
|
|
267
|
-
}
|
|
268
|
-
}
|
|
269
|
-
} catch (e) {}
|
|
270
|
-
}
|
|
271
|
-
return options;
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
function loadConfiguration() {
|
|
275
|
-
let config = {};
|
|
276
|
-
try {
|
|
277
|
-
for (const envPath of [path.join(os.homedir(), '.agent-insight', '.env'), path.join(os.homedir(), '.skill-insight', '.env')]) {
|
|
278
|
-
if (!fs.existsSync(envPath)) continue;
|
|
279
|
-
const content = fs.readFileSync(envPath, 'utf8');
|
|
280
|
-
content.split('\n').forEach(line => {
|
|
281
|
-
const match = line.match(/^\s*([\w_]+)\s*=\s*(.*)?\s*$/);
|
|
282
|
-
if (match) config[match[1]] = (match[2] || '').trim().replace(/^['"](.*)['"]$/, '$1');
|
|
283
|
-
});
|
|
284
|
-
}
|
|
285
|
-
} catch (e) {}
|
|
286
|
-
return {
|
|
287
|
-
apiKey: config['AGENT_INSIGHT_API_KEY'] || process.env.AGENT_INSIGHT_API_KEY,
|
|
288
|
-
host: config['AGENT_INSIGHT_HOST'] || process.env.AGENT_INSIGHT_HOST
|
|
289
|
-
};
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
function collectSessionMessages(sessionId) {
|
|
293
|
-
const messages = [];
|
|
294
|
-
logDebug(`collectSessionMessages: scanning ${sessionStore.size} entries for session ${sessionId}`);
|
|
295
|
-
for (const [mid, entry] of sessionStore.entries()) {
|
|
296
|
-
if (entry.info.sessionID === sessionId) {
|
|
297
|
-
// Calculate latency for this message if possible from parts
|
|
298
|
-
let partBasedDuration = 0;
|
|
299
|
-
if (entry.parts instanceof Map && entry.parts.size > 0) {
|
|
300
|
-
const parts = Array.from(entry.parts.values()).map(p => p.time?.start || 0).filter(t => t > 0).sort((a,b)=>a-b);
|
|
301
|
-
if (parts.length >= 1) {
|
|
302
|
-
const start = parts[0];
|
|
303
|
-
const end = parts[parts.length - 1];
|
|
304
|
-
partBasedDuration = Math.max(0, end - start);
|
|
305
|
-
}
|
|
306
|
-
}
|
|
307
|
-
|
|
308
|
-
const role = entry.info.role || 'unknown';
|
|
309
|
-
const content = entry.content || entry.info.content || "";
|
|
310
|
-
logDebug(`Found message in store: id=${mid}, role=${role}, content_len=${content.length}`);
|
|
311
|
-
|
|
312
|
-
messages.push({
|
|
313
|
-
role: role,
|
|
314
|
-
content: content,
|
|
315
|
-
tool_calls: entry.info.tool_calls || entry.info.toolCalls,
|
|
316
|
-
function_call: entry.info.function_call || entry.info.functionCall,
|
|
317
|
-
usage: entry.info.usage || entry.info.tokens,
|
|
318
|
-
timestamp: entry.info.created || entry.info.time?.created,
|
|
319
|
-
timeInfo: entry.info.time,
|
|
320
|
-
partBasedDuration: partBasedDuration,
|
|
321
|
-
modelID: entry.info.modelID,
|
|
322
|
-
model: entry.info.model,
|
|
323
|
-
agent: entry.info.agent
|
|
324
|
-
});
|
|
325
|
-
}
|
|
326
|
-
}
|
|
327
|
-
logDebug(`collectSessionMessages: collected ${messages.length} messages for ${sessionId}`);
|
|
328
|
-
return messages;
|
|
329
|
-
}
|
|
330
|
-
|
|
331
|
-
function cleanupOrphanedSessions() {
|
|
332
|
-
const now = Date.now();
|
|
333
|
-
const oneHourMs = 3600000;
|
|
334
|
-
|
|
335
|
-
for (const [childId, childData] of pendingChildSessions.entries()) {
|
|
336
|
-
try {
|
|
337
|
-
const childTime = new Date(childData.timestamp).getTime();
|
|
338
|
-
if (now - childTime > oneHourMs) {
|
|
339
|
-
logDebug(`Cleaning up orphaned child session ${childId}`);
|
|
340
|
-
pendingChildSessions.delete(childId);
|
|
341
|
-
}
|
|
342
|
-
} catch (e) {
|
|
343
|
-
logDebug(`Error checking child session ${childId}: ${e.message}`);
|
|
344
|
-
}
|
|
345
|
-
}
|
|
346
|
-
}
|
|
347
|
-
|
|
348
|
-
function findRootSessionId(sessionId) {
|
|
349
|
-
let cur = sessionId;
|
|
350
|
-
const visited = new Set();
|
|
351
|
-
while (cur && cur.startsWith('ses') && !visited.has(cur)) {
|
|
352
|
-
visited.add(cur);
|
|
353
|
-
const p = sessionParentById.get(cur);
|
|
354
|
-
if (!p || !p.startsWith('ses')) break;
|
|
355
|
-
cur = p;
|
|
356
|
-
}
|
|
357
|
-
return cur;
|
|
358
|
-
}
|
|
359
|
-
|
|
360
|
-
function collectSessionWithDescendants(rootSessionId) {
|
|
361
|
-
const messages = collectSessionMessages(rootSessionId);
|
|
362
|
-
const mergedSessionIds = [];
|
|
363
|
-
const visited = new Set();
|
|
364
|
-
const stack = Array.isArray(sessionGraph.get(rootSessionId)) ? [...sessionGraph.get(rootSessionId)] : [];
|
|
365
|
-
|
|
366
|
-
while (stack.length > 0) {
|
|
367
|
-
const sid = stack.pop();
|
|
368
|
-
if (!sid || visited.has(sid)) continue;
|
|
369
|
-
visited.add(sid);
|
|
370
|
-
|
|
371
|
-
const childData = pendingChildSessions.get(sid);
|
|
372
|
-
if (childData && childData.messages) {
|
|
373
|
-
logDebug(`Merging ${childData.messages.length} messages from child ${sid}`);
|
|
374
|
-
const name =
|
|
375
|
-
sessionAgentById.get(sid) ||
|
|
376
|
-
subagentTypeBySessionId.get(sid) ||
|
|
377
|
-
null;
|
|
378
|
-
const subagentMessages = childData.messages.map(msg => {
|
|
379
|
-
if (msg.role === 'assistant') {
|
|
380
|
-
return { ...msg, role: 'subagent', subagent_name: name || msg.agent, subagent_session_id: sid };
|
|
381
|
-
} else if (msg.role === 'user') {
|
|
382
|
-
return { ...msg, role: 'opencode' };
|
|
383
|
-
}
|
|
384
|
-
return msg;
|
|
385
|
-
});
|
|
386
|
-
messages.push(...subagentMessages);
|
|
387
|
-
mergedSessionIds.push(sid);
|
|
388
|
-
}
|
|
389
|
-
|
|
390
|
-
const next = sessionGraph.get(sid) || [];
|
|
391
|
-
for (const x of next) stack.push(x);
|
|
392
|
-
}
|
|
393
|
-
|
|
394
|
-
return { messages, mergedSessionIds };
|
|
395
|
-
}
|
|
396
|
-
|
|
397
|
-
export default async function WittySkillInsightPlugin(input) {
|
|
398
|
-
loadStore();
|
|
399
|
-
const { apiKey, host } = loadConfiguration();
|
|
400
|
-
if (!apiKey || !host) {
|
|
401
|
-
logDebug("Plugin disabled: Missing API Key or Host");
|
|
402
|
-
return {};
|
|
403
|
-
}
|
|
404
|
-
|
|
405
|
-
let parsedHost;
|
|
406
|
-
try {
|
|
407
|
-
const urlStr = host.match(/^https?:\/\//) ? host : `http://${host}`;
|
|
408
|
-
parsedHost = new URL(urlStr);
|
|
409
|
-
} catch (e) { return {}; }
|
|
410
|
-
|
|
411
|
-
const requestModule = parsedHost.protocol === 'https:' ? https : http;
|
|
412
|
-
|
|
413
|
-
// Auto-Sync Skills on Startup
|
|
414
|
-
try {
|
|
415
|
-
const syncScript = fs.existsSync(path.join(os.homedir(), '.agent-insight', 'sync_skills.ts'))
|
|
416
|
-
? path.join(os.homedir(), '.agent-insight', 'sync_skills.ts')
|
|
417
|
-
: path.join(os.homedir(), '.skill-insight', 'sync_skills.ts');
|
|
418
|
-
if (fs.existsSync(syncScript)) {
|
|
419
|
-
const cp = require('child_process');
|
|
420
|
-
// Run async to avoid blocking
|
|
421
|
-
const cmd = `npx -y tsx "${syncScript}" --agent opencode`;
|
|
422
|
-
|
|
423
|
-
// Only run if we are in a project directory that might use local skills?
|
|
424
|
-
// Or always run. Always run is safer for "latest active" requirement.
|
|
425
|
-
|
|
426
|
-
// Use exec to run in background
|
|
427
|
-
cp.exec(cmd, { cwd: process.cwd() }, (err, stdout, stderr) => {
|
|
428
|
-
if (err) logDebug(`Skill Sync Error: ${err.message}`);
|
|
429
|
-
else if (stdout) logDebug(`Skill Sync: ${stdout.trim()}`);
|
|
430
|
-
});
|
|
431
|
-
}
|
|
432
|
-
} catch (e) {
|
|
433
|
-
logDebug(`Skill Sync Init Exception: ${e.message}`);
|
|
434
|
-
}
|
|
435
|
-
|
|
436
|
-
// logDebug("Witty Plugin Initialized");
|
|
437
|
-
|
|
438
|
-
return {
|
|
439
|
-
event: async ({ event }) => {
|
|
440
|
-
logDebug(`Event received: ${event.type}`);
|
|
441
|
-
if (event.type && event.type.startsWith('tool')) {
|
|
442
|
-
logDebug(`Tool Payload: ${JSON.stringify(event.payload || event.properties || {})}`);
|
|
443
|
-
}
|
|
444
|
-
|
|
445
|
-
try {
|
|
446
|
-
const rawLogPath = path.join(os.homedir(), '.opencode', 'witty_plugin_raw_events.log');
|
|
447
|
-
if (!fs.existsSync(path.dirname(rawLogPath))) fs.mkdirSync(path.dirname(rawLogPath), { recursive: true });
|
|
448
|
-
fs.appendFileSync(rawLogPath, JSON.stringify({t: new Date().toISOString(), ...event}) + '\n');
|
|
449
|
-
} catch (e) {
|
|
450
|
-
logDebug(`Raw Log Error: ${e.message}`);
|
|
451
|
-
}
|
|
452
|
-
|
|
453
|
-
// logDebug(`Event: ${event.type}`);
|
|
454
|
-
|
|
455
|
-
try {
|
|
456
|
-
// Attempt to find session ID in various places
|
|
457
|
-
let sessionId = event.session_id || event.properties?.sessionID || event.payload?.session_id;
|
|
458
|
-
let eagerFlush = false;
|
|
459
|
-
|
|
460
|
-
if (event.type === 'session.created' || event.type === 'session.updated') {
|
|
461
|
-
const sessionInfo = event.properties?.info || event.payload?.info;
|
|
462
|
-
if (sessionInfo && sessionInfo.id) {
|
|
463
|
-
const sid = sessionInfo.id;
|
|
464
|
-
const pid = sessionInfo.parentID || sessionInfo.parentId || sessionInfo.parent_id;
|
|
465
|
-
if (pid && pid.startsWith('ses')) {
|
|
466
|
-
sessionParentById.set(sid, pid);
|
|
467
|
-
if (!sessionGraph.has(pid)) sessionGraph.set(pid, []);
|
|
468
|
-
if (!sessionGraph.get(pid).includes(sid)) {
|
|
469
|
-
sessionGraph.get(pid).push(sid);
|
|
470
|
-
logDebug(`Session created: ${sid} is child of ${pid}`);
|
|
471
|
-
}
|
|
472
|
-
}
|
|
473
|
-
}
|
|
474
|
-
}
|
|
475
|
-
|
|
476
|
-
// 1. Accumulate Message Metadata
|
|
477
|
-
if (event.type === 'message.created' || event.type === 'message.updated') {
|
|
478
|
-
let info = (event.payload && event.payload.message) || (event.properties && event.properties.info);
|
|
479
|
-
if (info && info.id) {
|
|
480
|
-
const msgId = info.id;
|
|
481
|
-
if (!sessionStore.has(msgId)) {
|
|
482
|
-
sessionStore.set(msgId, {
|
|
483
|
-
info: { sessionID: sessionId },
|
|
484
|
-
parts: new Map(),
|
|
485
|
-
content: ''
|
|
486
|
-
});
|
|
487
|
-
}
|
|
488
|
-
const entry = sessionStore.get(msgId);
|
|
489
|
-
if (!sessionId) sessionId = info.sessionID || info.sessionId || entry.info?.sessionID;
|
|
490
|
-
if (sessionId) entry.info.sessionID = sessionId;
|
|
491
|
-
// Merge info
|
|
492
|
-
Object.assign(entry.info, info);
|
|
493
|
-
if (info.tool_calls || info.toolCalls) entry.info.tool_calls = info.tool_calls || info.toolCalls;
|
|
494
|
-
if (info.function_call || info.functionCall) entry.info.function_call = info.function_call || info.functionCall;
|
|
495
|
-
|
|
496
|
-
if (entry.info?.sessionID && entry.info?.agent) {
|
|
497
|
-
if (!sessionAgentById.has(entry.info.sessionID)) {
|
|
498
|
-
sessionAgentById.set(entry.info.sessionID, entry.info.agent);
|
|
499
|
-
}
|
|
500
|
-
}
|
|
501
|
-
|
|
502
|
-
if (entry.info?.role === 'assistant' && (entry.info.finish || entry.info.time?.completed != null)) {
|
|
503
|
-
if (!eagerFlushMsgIds.has(msgId)) {
|
|
504
|
-
eagerFlushMsgIds.add(msgId);
|
|
505
|
-
if (eagerFlushMsgIds.size > 5000) {
|
|
506
|
-
eagerFlushMsgIds = new Set(Array.from(eagerFlushMsgIds).slice(-4000));
|
|
507
|
-
}
|
|
508
|
-
eagerFlush = true;
|
|
509
|
-
}
|
|
510
|
-
}
|
|
511
|
-
}
|
|
512
|
-
}
|
|
513
|
-
|
|
514
|
-
// 2. Accumulate Message Content Parts
|
|
515
|
-
if (event.type === 'message.part.created' || event.type === 'message.part.updated') {
|
|
516
|
-
let part = (event.payload && event.payload.part) || (event.properties && event.properties.part);
|
|
517
|
-
if (!part && event.payload) part = event.payload; // fallback
|
|
518
|
-
|
|
519
|
-
if (part && (part.messageID || part.message_id)) {
|
|
520
|
-
const msgId = part.messageID || part.message_id;
|
|
521
|
-
|
|
522
|
-
if (!sessionStore.has(msgId)) {
|
|
523
|
-
sessionStore.set(msgId, {
|
|
524
|
-
info: { sessionID: sessionId },
|
|
525
|
-
parts: new Map(),
|
|
526
|
-
toolParts: new Map(),
|
|
527
|
-
content: ''
|
|
528
|
-
});
|
|
529
|
-
}
|
|
530
|
-
const entry = sessionStore.get(msgId);
|
|
531
|
-
if (!sessionId) sessionId = entry.info?.sessionID || part.sessionID || part.session_id;
|
|
532
|
-
if (!(entry.parts instanceof Map)) entry.parts = new Map(Array.isArray(entry.parts) ? entry.parts : []);
|
|
533
|
-
if (entry.toolParts && !(entry.toolParts instanceof Map)) entry.toolParts = new Map(Array.isArray(entry.toolParts) ? entry.toolParts : []);
|
|
534
|
-
|
|
535
|
-
// Store part
|
|
536
|
-
const partId = part.id || `temp_${Date.now()}_${Math.random()}`;
|
|
537
|
-
|
|
538
|
-
if (part.type === 'tool') {
|
|
539
|
-
// Tool calls in OpenCode are often special parts
|
|
540
|
-
if (!entry.toolParts) entry.toolParts = new Map();
|
|
541
|
-
entry.toolParts.set(part.callID || partId, part);
|
|
542
|
-
} else {
|
|
543
|
-
entry.parts.set(partId, part);
|
|
544
|
-
}
|
|
545
|
-
|
|
546
|
-
// Reassemble content (text)
|
|
547
|
-
let full = "";
|
|
548
|
-
const sortedParts = Array.from(entry.parts.values()).sort((a, b) => {
|
|
549
|
-
const ta = a.time?.start || (a.meta && a.meta.start) || 0;
|
|
550
|
-
const tb = b.time?.start || (b.meta && b.meta.start) || 0;
|
|
551
|
-
return ta - tb;
|
|
552
|
-
});
|
|
553
|
-
|
|
554
|
-
for (const p of sortedParts) {
|
|
555
|
-
if (p.text) full += p.text;
|
|
556
|
-
else if (p.content) full += p.content;
|
|
557
|
-
}
|
|
558
|
-
entry.content = full;
|
|
559
|
-
|
|
560
|
-
// Process Tool Calls for storage
|
|
561
|
-
if (entry.toolParts && entry.toolParts.size > 0) {
|
|
562
|
-
const tool_calls = [];
|
|
563
|
-
for (const tp of entry.toolParts.values()) {
|
|
564
|
-
if (tp.tool && tp.state) {
|
|
565
|
-
// Try to infer timing from common OpenCode shapes
|
|
566
|
-
const startRaw =
|
|
567
|
-
tp.time?.start ??
|
|
568
|
-
tp.time?.created ??
|
|
569
|
-
tp.meta?.start ??
|
|
570
|
-
tp.meta?.created ??
|
|
571
|
-
tp.state?.time?.start ??
|
|
572
|
-
tp.state?.time?.created ??
|
|
573
|
-
tp.state?.started_at ??
|
|
574
|
-
tp.state?.startTime ??
|
|
575
|
-
tp.state?.start_time ??
|
|
576
|
-
null;
|
|
577
|
-
const endRaw =
|
|
578
|
-
tp.time?.completed ??
|
|
579
|
-
tp.time?.end ??
|
|
580
|
-
tp.meta?.completed ??
|
|
581
|
-
tp.meta?.end ??
|
|
582
|
-
tp.state?.time?.completed ??
|
|
583
|
-
tp.state?.time?.end ??
|
|
584
|
-
tp.state?.completed_at ??
|
|
585
|
-
tp.state?.endTime ??
|
|
586
|
-
tp.state?.end_time ??
|
|
587
|
-
null;
|
|
588
|
-
const timing = buildTiming(startRaw, endRaw);
|
|
589
|
-
|
|
590
|
-
tool_calls.push({
|
|
591
|
-
id: tp.callID,
|
|
592
|
-
type: 'function',
|
|
593
|
-
function: {
|
|
594
|
-
name: tp.tool,
|
|
595
|
-
arguments: JSON.stringify(tp.state.input || {})
|
|
596
|
-
},
|
|
597
|
-
state: tp.state.status,
|
|
598
|
-
output: tp.state.output,
|
|
599
|
-
timing: timing
|
|
600
|
-
});
|
|
601
|
-
|
|
602
|
-
// Detect task tool calls and extract subagent session_id
|
|
603
|
-
if (tp.tool === 'task' && tp.state.output) {
|
|
604
|
-
try {
|
|
605
|
-
const taskOutput = tp.state.output;
|
|
606
|
-
let subagentSessionId = null;
|
|
607
|
-
const m1 = taskOutput.match(/<task_metadata>[\s\S]*?session_id:\s*(ses_[A-Za-z0-9]+)[\s\S]*?<\/task_metadata>/i);
|
|
608
|
-
const m2 = taskOutput.match(/session_id:\s*(ses_[A-Za-z0-9]+)/i);
|
|
609
|
-
const m3 = taskOutput.match(/task\(\s*session_id\s*=\s*\"(ses_[A-Za-z0-9]+)\"/i);
|
|
610
|
-
const m4 = taskOutput.match(/task_id:\s*(\w+)/i);
|
|
611
|
-
const candidate = (m1 && m1[1]) || (m2 && m2[1]) || (m3 && m3[1]) || (m4 && m4[1]) || null;
|
|
612
|
-
if (candidate && String(candidate).startsWith('ses')) subagentSessionId = String(candidate);
|
|
613
|
-
|
|
614
|
-
if (subagentSessionId) {
|
|
615
|
-
const parentSessionId = entry.info.sessionID || sessionId;
|
|
616
|
-
if (parentSessionId) {
|
|
617
|
-
if (!sessionGraph.has(parentSessionId)) sessionGraph.set(parentSessionId, []);
|
|
618
|
-
if (!sessionGraph.get(parentSessionId).includes(subagentSessionId)) {
|
|
619
|
-
sessionGraph.get(parentSessionId).push(subagentSessionId);
|
|
620
|
-
logDebug(`Task detected: ${subagentSessionId} is child of ${parentSessionId}`);
|
|
621
|
-
}
|
|
622
|
-
if (!sessionParentById.has(subagentSessionId)) {
|
|
623
|
-
sessionParentById.set(subagentSessionId, parentSessionId);
|
|
624
|
-
}
|
|
625
|
-
}
|
|
626
|
-
|
|
627
|
-
const t = tp.state?.input?.subagent_type;
|
|
628
|
-
if (t && !subagentTypeBySessionId.has(subagentSessionId)) {
|
|
629
|
-
subagentTypeBySessionId.set(subagentSessionId, t);
|
|
630
|
-
}
|
|
631
|
-
}
|
|
632
|
-
} catch (e) {
|
|
633
|
-
logDebug(`Error parsing task output: ${e.message}`);
|
|
634
|
-
}
|
|
635
|
-
}
|
|
636
|
-
}
|
|
637
|
-
}
|
|
638
|
-
if (tool_calls.length > 0) {
|
|
639
|
-
entry.info.tool_calls = tool_calls;
|
|
640
|
-
}
|
|
641
|
-
}
|
|
642
|
-
|
|
643
|
-
// Update SessionID if found in event
|
|
644
|
-
if (sessionId && !entry.info.sessionID) entry.info.sessionID = sessionId;
|
|
645
|
-
}
|
|
646
|
-
}
|
|
647
|
-
|
|
648
|
-
if (event.type === 'message.part.delta') {
|
|
649
|
-
const props = event.properties || event.payload || {};
|
|
650
|
-
const msgId = props.messageID || props.message_id;
|
|
651
|
-
const partId = props.partID || props.part_id;
|
|
652
|
-
const field = props.field;
|
|
653
|
-
const delta = props.delta;
|
|
654
|
-
|
|
655
|
-
if (msgId && partId && field && typeof delta === 'string') {
|
|
656
|
-
if (!sessionStore.has(msgId)) {
|
|
657
|
-
sessionStore.set(msgId, {
|
|
658
|
-
info: { sessionID: sessionId },
|
|
659
|
-
parts: new Map(),
|
|
660
|
-
toolParts: new Map(),
|
|
661
|
-
content: ''
|
|
662
|
-
});
|
|
663
|
-
}
|
|
664
|
-
|
|
665
|
-
const entry = sessionStore.get(msgId);
|
|
666
|
-
if (!sessionId) sessionId = entry.info?.sessionID;
|
|
667
|
-
if (!(entry.parts instanceof Map)) entry.parts = new Map(Array.isArray(entry.parts) ? entry.parts : []);
|
|
668
|
-
|
|
669
|
-
const dedupeKey = `${msgId}:${partId}:${field}`;
|
|
670
|
-
const lastDelta = lastDeltaByPartField.get(dedupeKey);
|
|
671
|
-
if (lastDelta !== delta) {
|
|
672
|
-
lastDeltaByPartField.set(dedupeKey, delta);
|
|
673
|
-
if (lastDeltaByPartField.size > 5000) {
|
|
674
|
-
for (const k of lastDeltaByPartField.keys()) {
|
|
675
|
-
lastDeltaByPartField.delete(k);
|
|
676
|
-
if (lastDeltaByPartField.size <= 4000) break;
|
|
677
|
-
}
|
|
678
|
-
}
|
|
679
|
-
|
|
680
|
-
const existingPart = entry.parts.get(partId) || {
|
|
681
|
-
id: partId,
|
|
682
|
-
messageID: msgId,
|
|
683
|
-
sessionID: sessionId,
|
|
684
|
-
type: 'text'
|
|
685
|
-
};
|
|
686
|
-
const prev = typeof existingPart[field] === 'string' ? existingPart[field] : '';
|
|
687
|
-
existingPart[field] = prev + delta;
|
|
688
|
-
entry.parts.set(partId, existingPart);
|
|
689
|
-
|
|
690
|
-
let full = "";
|
|
691
|
-
const sortedParts = Array.from(entry.parts.values()).sort((a, b) => {
|
|
692
|
-
const ta = a.time?.start || (a.meta && a.meta.start) || 0;
|
|
693
|
-
const tb = b.time?.start || (b.meta && b.meta.start) || 0;
|
|
694
|
-
return ta - tb;
|
|
695
|
-
});
|
|
696
|
-
|
|
697
|
-
for (const p of sortedParts) {
|
|
698
|
-
if (p.text) full += p.text;
|
|
699
|
-
else if (p.content) full += p.content;
|
|
700
|
-
}
|
|
701
|
-
entry.content = full;
|
|
702
|
-
}
|
|
703
|
-
}
|
|
704
|
-
}
|
|
705
|
-
|
|
706
|
-
// 3. Upload on Session Idle
|
|
707
|
-
if (event.type === "session.idle" || eagerFlush) {
|
|
708
|
-
if (!sessionId || !sessionId.startsWith("ses")) return;
|
|
709
|
-
|
|
710
|
-
const isIdleTrigger = event.type === "session.idle";
|
|
711
|
-
if (!isIdleTrigger) {
|
|
712
|
-
const THROTTLE_MS = Number(process.env.WITTY_EAGER_FLUSH_THROTTLE_MS || 2000);
|
|
713
|
-
const throttleMs = Number.isFinite(THROTTLE_MS) && THROTTLE_MS > 0 ? THROTTLE_MS : 0;
|
|
714
|
-
if (throttleMs > 0) {
|
|
715
|
-
const now = Date.now();
|
|
716
|
-
const last = lastEagerFlushAtBySessionId.get(sessionId) || 0;
|
|
717
|
-
if (now - last < throttleMs) {
|
|
718
|
-
logDebug(`Skipping eagerFlush upload for ${sessionId}: throttled (${now - last}ms < ${throttleMs}ms)`);
|
|
719
|
-
return;
|
|
720
|
-
}
|
|
721
|
-
lastEagerFlushAtBySessionId.set(sessionId, now);
|
|
722
|
-
}
|
|
723
|
-
}
|
|
724
|
-
|
|
725
|
-
// Reload store from disk to pick up any data written by
|
|
726
|
-
// concurrent child processes (e.g. opencode run executed
|
|
727
|
-
// from within the opencode interactive interface).
|
|
728
|
-
loadStore();
|
|
729
|
-
|
|
730
|
-
let foundParentId = null;
|
|
731
|
-
const directParent = sessionParentById.get(sessionId);
|
|
732
|
-
if (directParent && Array.isArray(sessionGraph.get(directParent)) && sessionGraph.get(directParent).includes(sessionId)) {
|
|
733
|
-
foundParentId = directParent;
|
|
734
|
-
logDebug(`Found parent ${foundParentId} for for child ${sessionId} from sessionParentById`);
|
|
735
|
-
} else {
|
|
736
|
-
for (const [potentialParent, childIds] of sessionGraph.entries()) {
|
|
737
|
-
if (childIds.includes(sessionId)) {
|
|
738
|
-
foundParentId = potentialParent;
|
|
739
|
-
logDebug(`Found parent ${foundParentId} for for child ${sessionId} from sessionGraph`);
|
|
740
|
-
break;
|
|
741
|
-
}
|
|
742
|
-
}
|
|
743
|
-
}
|
|
744
|
-
|
|
745
|
-
if (foundParentId) {
|
|
746
|
-
logDebug(`Child ${sessionId} detected with parent ${foundParentId}`);
|
|
747
|
-
|
|
748
|
-
// Store child session data and wait for parent
|
|
749
|
-
if (!sessionGraph.has(foundParentId)) {
|
|
750
|
-
sessionGraph.set(foundParentId, []);
|
|
751
|
-
}
|
|
752
|
-
if (!sessionGraph.get(foundParentId).includes(sessionId)) {
|
|
753
|
-
sessionGraph.get(foundParentId).push(sessionId);
|
|
754
|
-
}
|
|
755
|
-
|
|
756
|
-
// Collect and store child session data
|
|
757
|
-
const childMessages = collectSessionMessages(sessionId);
|
|
758
|
-
if (childMessages.length > 0) {
|
|
759
|
-
pendingChildSessions.set(sessionId, {
|
|
760
|
-
parent_id: foundParentId,
|
|
761
|
-
messages: childMessages,
|
|
762
|
-
timestamp: new Date().toISOString()
|
|
763
|
-
});
|
|
764
|
-
logDebug(`Stored ${childMessages.length} messages for child session ${sessionId}`);
|
|
765
|
-
}
|
|
766
|
-
|
|
767
|
-
const rootId = findRootSessionId(foundParentId) || foundParentId;
|
|
768
|
-
if (!rootId || rootId === sessionId) return;
|
|
769
|
-
sessionId = rootId;
|
|
770
|
-
}
|
|
771
|
-
|
|
772
|
-
logDebug(`Session Idle: ${sessionId}. Messages in store: ${sessionStore.size}`);
|
|
773
|
-
|
|
774
|
-
// This is a parent session, collect all messages including children
|
|
775
|
-
const { messages, mergedSessionIds } = collectSessionWithDescendants(sessionId);
|
|
776
|
-
|
|
777
|
-
if (messages.length === 0) {
|
|
778
|
-
logDebug(`No messages found for session ${sessionId}, skipping upload.`);
|
|
779
|
-
return;
|
|
780
|
-
}
|
|
781
|
-
|
|
782
|
-
// Cleanup child session data after successful upload
|
|
783
|
-
for (const childId of mergedSessionIds) {
|
|
784
|
-
pendingChildSessions.delete(childId);
|
|
785
|
-
logDebug(`Cleaned up child session ${childId}`);
|
|
786
|
-
}
|
|
787
|
-
|
|
788
|
-
// Cleanup orphaned child sessions (older than 1 hour)
|
|
789
|
-
cleanupOrphanedSessions();
|
|
790
|
-
|
|
791
|
-
// Sort messages by timestamp safely
|
|
792
|
-
messages.sort((a, b) => {
|
|
793
|
-
const ta = Number(a.timestamp) || 0;
|
|
794
|
-
const tb = Number(b.timestamp) || 0;
|
|
795
|
-
return ta - tb;
|
|
796
|
-
});
|
|
797
|
-
|
|
798
|
-
// Analyze
|
|
799
|
-
let totalTokens = 0;
|
|
800
|
-
let totalLatencyMs = 0;
|
|
801
|
-
let firstUserQuery = "";
|
|
802
|
-
let lastAssistantContent = "";
|
|
803
|
-
let model = "";
|
|
804
|
-
let totalInputTokens = 0;
|
|
805
|
-
let totalOutputTokens = 0;
|
|
806
|
-
let totalCacheReadInputTokens = 0;
|
|
807
|
-
let totalCacheCreationInputTokens = 0;
|
|
808
|
-
let totalReasoningTokens = 0;
|
|
809
|
-
let llmCallCount = 0;
|
|
810
|
-
let toolCallCount = 0;
|
|
811
|
-
let toolCallErrorCount = 0;
|
|
812
|
-
let maxSingleCallTokens = 0;
|
|
813
|
-
|
|
814
|
-
let firstTs = Number.MAX_SAFE_INTEGER;
|
|
815
|
-
let lastTs = 0;
|
|
816
|
-
|
|
817
|
-
for (const m of messages) {
|
|
818
|
-
if (m.role === 'user' && !firstUserQuery) firstUserQuery = m.content;
|
|
819
|
-
const isCompletion = m.role === 'assistant' || m.role === 'subagent';
|
|
820
|
-
if (m.role === 'assistant') {
|
|
821
|
-
lastAssistantContent = m.content;
|
|
822
|
-
if (m.model) model = m.model;
|
|
823
|
-
else if (m.modelID) model = m.modelID;
|
|
824
|
-
}
|
|
825
|
-
|
|
826
|
-
const t1 = toMsTimestamp(m.timestamp) || 0;
|
|
827
|
-
const t2 = toMsTimestamp(m.timeInfo?.completed) || 0;
|
|
828
|
-
const t3 = toMsTimestamp(m.timeInfo?.created) || 0;
|
|
829
|
-
|
|
830
|
-
if (t1 > 0) {
|
|
831
|
-
firstTs = Math.min(firstTs, t1);
|
|
832
|
-
lastTs = Math.max(lastTs, t1);
|
|
833
|
-
}
|
|
834
|
-
if (t2 > 0) {
|
|
835
|
-
lastTs = Math.max(lastTs, t2);
|
|
836
|
-
}
|
|
837
|
-
if (t3 > 0) {
|
|
838
|
-
firstTs = Math.min(firstTs, t3);
|
|
839
|
-
lastTs = Math.max(lastTs, t3);
|
|
840
|
-
}
|
|
841
|
-
|
|
842
|
-
if (isCompletion) {
|
|
843
|
-
llmCallCount++;
|
|
844
|
-
|
|
845
|
-
// Token logic
|
|
846
|
-
const u = m.usage;
|
|
847
|
-
if (u) {
|
|
848
|
-
if (u.total !== undefined) {
|
|
849
|
-
totalTokens += Number(u.total);
|
|
850
|
-
} else {
|
|
851
|
-
totalTokens += Number(u.input_tokens || u.input || 0) + Number(u.output_tokens || u.output || 0);
|
|
852
|
-
if (u.cache) {
|
|
853
|
-
totalTokens += Number(u.cache.read || 0) + Number(u.cache.write || 0);
|
|
854
|
-
}
|
|
855
|
-
totalTokens += Number(u.cache_creation_input_tokens || 0) + Number(u.cache_read_input_tokens || 0);
|
|
856
|
-
}
|
|
857
|
-
// Extended metrics: separate input/output token counts
|
|
858
|
-
const cacheReadToks = Number(u.cache?.read || u.cache_read_input_tokens || 0);
|
|
859
|
-
const cacheCreateToks = Number(u.cache?.write || u.cache_creation_input_tokens || 0);
|
|
860
|
-
const inputToks = Number(u.input_tokens || u.input || 0); // base input only (excludes cache)
|
|
861
|
-
const rawOutputToks = Number(u.output_tokens || u.output || 0);
|
|
862
|
-
const reasoningToks = Number(u.reasoning || u.reasoning_tokens || u.completion_tokens_details?.reasoning_tokens || 0);
|
|
863
|
-
// OpenCode reports reasoning separately from output; DeepSeek API includes it in output.
|
|
864
|
-
// Normalize: output_tokens should always include reasoning tokens.
|
|
865
|
-
const outputToks = (u.reasoning !== undefined && reasoningToks > 0 && rawOutputToks < reasoningToks)
|
|
866
|
-
? rawOutputToks + reasoningToks
|
|
867
|
-
: rawOutputToks;
|
|
868
|
-
totalInputTokens += inputToks;
|
|
869
|
-
totalOutputTokens += outputToks;
|
|
870
|
-
totalCacheReadInputTokens += cacheReadToks;
|
|
871
|
-
totalCacheCreationInputTokens += cacheCreateToks;
|
|
872
|
-
totalReasoningTokens += reasoningToks;
|
|
873
|
-
const callTotal = inputToks + cacheReadToks + cacheCreateToks + outputToks;
|
|
874
|
-
if (callTotal > maxSingleCallTokens) maxSingleCallTokens = callTotal;
|
|
875
|
-
}
|
|
876
|
-
|
|
877
|
-
// Count tool calls from this message
|
|
878
|
-
if (m.tool_calls && Array.isArray(m.tool_calls)) {
|
|
879
|
-
toolCallCount += m.tool_calls.length;
|
|
880
|
-
for (const tc of m.tool_calls) {
|
|
881
|
-
if (tc.state === 'error' || tc.state === 'failed') {
|
|
882
|
-
toolCallErrorCount++;
|
|
883
|
-
}
|
|
884
|
-
}
|
|
885
|
-
}
|
|
886
|
-
}
|
|
887
|
-
}
|
|
888
|
-
|
|
889
|
-
if (firstTs !== Number.MAX_SAFE_INTEGER && lastTs > firstTs) {
|
|
890
|
-
totalLatencyMs = lastTs - firstTs;
|
|
891
|
-
}
|
|
892
|
-
|
|
893
|
-
logDebug(`Uploading session ${sessionId}. Latency: ${totalLatencyMs}ms, Messages: ${messages.length}`);
|
|
894
|
-
|
|
895
|
-
const payload = {
|
|
896
|
-
task_id: sessionId,
|
|
897
|
-
query: firstUserQuery || `OpenCode Session ${sessionId}`,
|
|
898
|
-
framework: 'opencode',
|
|
899
|
-
model: model,
|
|
900
|
-
tokens: totalTokens,
|
|
901
|
-
latency: totalLatencyMs / 1000,
|
|
902
|
-
input_tokens: totalInputTokens,
|
|
903
|
-
output_tokens: totalOutputTokens,
|
|
904
|
-
tool_call_count: toolCallCount,
|
|
905
|
-
tool_call_error_count: toolCallErrorCount,
|
|
906
|
-
llm_call_count: llmCallCount,
|
|
907
|
-
cache_read_input_tokens: totalCacheReadInputTokens,
|
|
908
|
-
cache_creation_input_tokens: totalCacheCreationInputTokens,
|
|
909
|
-
max_single_call_tokens: maxSingleCallTokens,
|
|
910
|
-
reasoning_tokens: totalReasoningTokens,
|
|
911
|
-
final_result: lastAssistantContent,
|
|
912
|
-
interactions: messages.map(m => ({
|
|
913
|
-
role: m.role,
|
|
914
|
-
content: m.content,
|
|
915
|
-
tool_calls: m.tool_calls || m.toolCalls,
|
|
916
|
-
function_call: m.function_call || m.functionCall,
|
|
917
|
-
usage: m.usage,
|
|
918
|
-
timestamp: m.timestamp,
|
|
919
|
-
timeInfo: m.timeInfo,
|
|
920
|
-
agent: m.agent,
|
|
921
|
-
subagent_name: m.subagent_name,
|
|
922
|
-
subagent_session_id: m.subagent_session_id
|
|
923
|
-
})),
|
|
924
|
-
timestamp: new Date().toISOString()
|
|
925
|
-
};
|
|
926
|
-
|
|
927
|
-
let lastTs = 0;
|
|
928
|
-
for (const m of messages) {
|
|
929
|
-
const t1 = toMsTimestamp(m.timestamp) || 0;
|
|
930
|
-
const t2 = toMsTimestamp(m.timeInfo?.completed) || 0;
|
|
931
|
-
const t3 = toMsTimestamp(m.timeInfo?.created) || 0;
|
|
932
|
-
lastTs = Math.max(lastTs, t1, t2, t3);
|
|
933
|
-
}
|
|
934
|
-
const lastAssistantLen = (lastAssistantContent || '').length;
|
|
935
|
-
|
|
936
|
-
const normalize = (v) => {
|
|
937
|
-
if (typeof v === 'number') return { count: v, lastAssistantLen: 0, lastTs: 0 };
|
|
938
|
-
if (v && typeof v === 'object') {
|
|
939
|
-
return {
|
|
940
|
-
count: Number(v.count || 0),
|
|
941
|
-
lastAssistantLen: Number(v.lastAssistantLen || 0),
|
|
942
|
-
lastTs: Number(v.lastTs || 0)
|
|
943
|
-
};
|
|
944
|
-
}
|
|
945
|
-
return { count: 0, lastAssistantLen: 0, lastTs: 0 };
|
|
946
|
-
};
|
|
947
|
-
|
|
948
|
-
const prevSig = normalize(uploadedSessions.get(sessionId));
|
|
949
|
-
const shouldSkip =
|
|
950
|
-
messages.length <= prevSig.count &&
|
|
951
|
-
lastAssistantLen <= prevSig.lastAssistantLen &&
|
|
952
|
-
lastTs <= prevSig.lastTs;
|
|
953
|
-
|
|
954
|
-
if (shouldSkip) {
|
|
955
|
-
logDebug(`Session ${sessionId} already uploaded (count=${prevSig.count}, lastAssistantLen=${prevSig.lastAssistantLen}, lastTs=${prevSig.lastTs}) (cur: count=${messages.length}, lastAssistantLen=${lastAssistantLen}, lastTs=${lastTs}), skipping.`);
|
|
956
|
-
return;
|
|
957
|
-
}
|
|
958
|
-
uploadedSessions.set(sessionId, { count: messages.length, lastAssistantLen, lastTs });
|
|
959
|
-
|
|
960
|
-
const body = JSON.stringify(payload);
|
|
961
|
-
logDebug(`Payload Body Size: ${Buffer.byteLength(body)} bytes`);
|
|
962
|
-
|
|
963
|
-
const options = getRequestOptions(parsedHost, apiKey, Buffer.byteLength(body));
|
|
964
|
-
const isHttps = parsedHost.protocol === 'https:';
|
|
965
|
-
|
|
966
|
-
const cp = require('child_process');
|
|
967
|
-
const reqId = Date.now() + '_' + Math.floor(Math.random() * 10000);
|
|
968
|
-
const tmpDir = os.tmpdir();
|
|
969
|
-
const payloadPath = path.join(tmpDir, `witty_req_${reqId}.json`);
|
|
970
|
-
const scriptPath = path.join(tmpDir, `witty_upload_${reqId}.js`);
|
|
971
|
-
const logPath = path.join(tmpDir, `witty_upload_${reqId}.log`);
|
|
972
|
-
|
|
973
|
-
const uploaderScript = `
|
|
974
|
-
const http = require('http');
|
|
975
|
-
const https = require('https');
|
|
976
|
-
const fs = require('fs');
|
|
977
|
-
|
|
978
|
-
try {
|
|
979
|
-
const reqModule = ${isHttps ? 'https' : 'http'};
|
|
980
|
-
const options = ${JSON.stringify(options)};
|
|
981
|
-
const payloadPath = ${JSON.stringify(payloadPath)};
|
|
982
|
-
const scriptPath = ${JSON.stringify(scriptPath)};
|
|
983
|
-
const logPath = ${JSON.stringify(logPath)};
|
|
984
|
-
const body = fs.readFileSync(payloadPath);
|
|
985
|
-
options.headers['Content-Length'] = body.length;
|
|
986
|
-
|
|
987
|
-
const req = reqModule.request(options, (res) => {
|
|
988
|
-
let resBody = '';
|
|
989
|
-
res.on('data', (chunk) => { resBody += chunk; });
|
|
990
|
-
res.on('end', () => {
|
|
991
|
-
try { fs.appendFileSync(logPath, new Date().toISOString() + ' Upload OK status=' + res.statusCode + ' body=' + resBody + '\\n'); } catch(e){}
|
|
992
|
-
try { fs.unlinkSync(payloadPath); } catch(e){}
|
|
993
|
-
try { fs.unlinkSync(scriptPath); } catch(e){}
|
|
994
|
-
});
|
|
995
|
-
});
|
|
996
|
-
|
|
997
|
-
req.on('error', (err) => {
|
|
998
|
-
try { fs.appendFileSync(logPath, new Date().toISOString() + ' Upload ERROR: ' + err.message + '\\n'); } catch(e){}
|
|
999
|
-
try { fs.unlinkSync(payloadPath); } catch(e){}
|
|
1000
|
-
try { fs.unlinkSync(scriptPath); } catch(e){}
|
|
1001
|
-
});
|
|
1002
|
-
|
|
1003
|
-
req.setTimeout(15000, () => {
|
|
1004
|
-
req.destroy();
|
|
1005
|
-
try { fs.appendFileSync(logPath, new Date().toISOString() + ' Upload TIMEOUT\\n'); } catch(e){}
|
|
1006
|
-
try { fs.unlinkSync(payloadPath); } catch(e){}
|
|
1007
|
-
try { fs.unlinkSync(scriptPath); } catch(e){}
|
|
1008
|
-
});
|
|
1009
|
-
|
|
1010
|
-
req.end(body);
|
|
1011
|
-
} catch (e) {
|
|
1012
|
-
try { fs.appendFileSync(${JSON.stringify(path.join(os.tmpdir(), 'witty_upload_crash.log'))}, new Date().toISOString() + ' CRASH: ' + e.message + '\\n'); } catch(x){}
|
|
1013
|
-
process.exit(1);
|
|
1014
|
-
}
|
|
1015
|
-
`;
|
|
1016
|
-
|
|
1017
|
-
fs.writeFileSync(payloadPath, body);
|
|
1018
|
-
fs.writeFileSync(scriptPath, uploaderScript);
|
|
1019
|
-
|
|
1020
|
-
// process.execPath in OpenCode's plugin runtime points to the
|
|
1021
|
-
// OpenCode binary itself (e.g. ~/.opencode/bin/opencode), NOT node.
|
|
1022
|
-
// We must explicitly resolve the node binary path.
|
|
1023
|
-
let nodeBin = 'node';
|
|
1024
|
-
try {
|
|
1025
|
-
const nodeCmd = process.platform === 'win32' ? 'where node' : 'which node';
|
|
1026
|
-
nodeBin = cp.execSync(nodeCmd, { encoding: 'utf8', timeout: 3000 }).trim() || 'node';
|
|
1027
|
-
if (process.platform === 'win32') {
|
|
1028
|
-
const lines = nodeBin.split('\n');
|
|
1029
|
-
nodeBin = lines[0].trim() || 'node';
|
|
1030
|
-
}
|
|
1031
|
-
} catch (e) {
|
|
1032
|
-
logDebug(`Could not resolve node path, falling back to 'node'`);
|
|
1033
|
-
}
|
|
1034
|
-
|
|
1035
|
-
logDebug(`Launching uploader: node=${nodeBin}, script=${scriptPath}`);
|
|
1036
|
-
try {
|
|
1037
|
-
const uploader = cp.spawn(nodeBin, [scriptPath], {
|
|
1038
|
-
detached: true,
|
|
1039
|
-
stdio: ['ignore', fs.openSync(logPath, 'a'), fs.openSync(logPath, 'a')],
|
|
1040
|
-
windowsHide: true
|
|
1041
|
-
});
|
|
1042
|
-
uploader.unref();
|
|
1043
|
-
logDebug(`Uploader spawned successfully (PID: ${uploader.pid})`);
|
|
1044
|
-
} catch (spawnErr) {
|
|
1045
|
-
logDebug(`spawn uploader error: ${spawnErr.message}`);
|
|
1046
|
-
}
|
|
1047
|
-
|
|
1048
|
-
/*
|
|
1049
|
-
// Cleanup - DISABLED
|
|
1050
|
-
// We want to accumulate history.
|
|
1051
|
-
for (const [msgId, entry] of sessionStore.entries()) {
|
|
1052
|
-
if (entry.info.sessionID === sessionId) sessionStore.delete(msgId);
|
|
1053
|
-
}
|
|
1054
|
-
*/
|
|
1055
|
-
}
|
|
1056
|
-
} catch (err) {
|
|
1057
|
-
logDebug(`Plugin Exception: ${err.message}`);
|
|
1058
|
-
} finally {
|
|
1059
|
-
saveStore();
|
|
1060
|
-
}
|
|
1061
|
-
}
|
|
1062
|
-
};
|
|
1063
|
-
}
|