mirror of
https://github.com/theodore-song/polymarket-analyst.git
synced 2026-08-24 04:58:08 +00:00
Resolve current runtime branch state
This commit is contained in:
@@ -34,7 +34,7 @@ jobs:
|
||||
- run: node scripts/run-autonomous-cycle.mjs
|
||||
env:
|
||||
ARENA_URL: https://polymarket-site-eta.vercel.app
|
||||
EXPECTED_BUILD: "90"
|
||||
EXPECTED_BUILD: "91"
|
||||
RUNTIME_BRANCH: runtime-state
|
||||
RUNTIME_STATE_PATH: runtime/state.json
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
@@ -20,7 +20,7 @@ market snapshots. During an outage, cycles continue locally; cached entries are
|
||||
allowed for 90 minutes, older snapshots become mark-only, and all cached data
|
||||
expires after 24 hours.
|
||||
|
||||
Build 90 adds a headless GitHub Actions runtime that checks the production site
|
||||
Build 91 adds a headless GitHub Actions runtime that checks the production site
|
||||
at seven minutes past every hour, continues from the previous agent snapshot,
|
||||
and runs the next due paper cycle even when no browser is open. It writes a
|
||||
sanitized snapshot to the `runtime-state` branch and `/api/state` uses that as a
|
||||
|
||||
+28
-7
@@ -6,6 +6,8 @@ const STATE_VERSION_PREFIX = process.env.PMA_STATE_VERSION_PREFIX || "shared/sta
|
||||
const DATABASE_STATE_KEY = process.env.PMA_DATABASE_STATE_KEY || "polymarket-arena";
|
||||
const GITHUB_RUNTIME_STATE_URL = process.env.PMA_GITHUB_RUNTIME_STATE_URL
|
||||
|| "https://raw.githubusercontent.com/theodore-song/polymarket-analyst/runtime-state/runtime/state.json";
|
||||
const GITHUB_RUNTIME_CONTENTS_URL = process.env.PMA_GITHUB_RUNTIME_CONTENTS_URL
|
||||
|| "https://api.github.com/repos/theodore-song/polymarket-analyst/contents/runtime/state.json?ref=runtime-state";
|
||||
const AGENTS_KEY = "pma_agents_v2";
|
||||
const SUG_KEY = "pma_suggestions_v5";
|
||||
const PAPER_KEY = "pma_paper_accounts_v1";
|
||||
@@ -106,20 +108,39 @@ async function readJsonBlob() {
|
||||
}
|
||||
|
||||
async function readGithubRuntimeState() {
|
||||
if (!GITHUB_RUNTIME_STATE_URL) return null;
|
||||
if (!GITHUB_RUNTIME_CONTENTS_URL && !GITHUB_RUNTIME_STATE_URL) return null;
|
||||
const controller = new AbortController();
|
||||
const timeout = setTimeout(() => controller.abort(), 8000);
|
||||
try {
|
||||
const url = new URL(GITHUB_RUNTIME_STATE_URL);
|
||||
url.searchParams.set("runtime", `${Date.now()}-${Math.random().toString(36).slice(2)}`);
|
||||
const response = await fetch(url, {
|
||||
if (GITHUB_RUNTIME_CONTENTS_URL) {
|
||||
const contentsUrl = new URL(GITHUB_RUNTIME_CONTENTS_URL);
|
||||
contentsUrl.searchParams.set("runtime", `${Date.now()}-${Math.random().toString(36).slice(2)}`);
|
||||
const contentsResponse = await fetch(contentsUrl, {
|
||||
cache: "no-store",
|
||||
headers: { Accept: "application/vnd.github+json", "Cache-Control": "no-cache", "User-Agent": "polymarket-arena-state" },
|
||||
signal: controller.signal,
|
||||
});
|
||||
if (contentsResponse.ok) {
|
||||
const file = await contentsResponse.json();
|
||||
if (!file || typeof file.content !== "string") throw new Error("GitHub runtime contents response is missing file data");
|
||||
const decoded = Buffer.from(file.content.replace(/\s/g, ""), "base64").toString("utf8");
|
||||
return sanitizeGithubRuntimeState(JSON.parse(decoded));
|
||||
}
|
||||
if (contentsResponse.status !== 403 && contentsResponse.status !== 429 && contentsResponse.status !== 404) {
|
||||
throw new Error(`GitHub runtime contents returned HTTP ${contentsResponse.status}`);
|
||||
}
|
||||
}
|
||||
if (!GITHUB_RUNTIME_STATE_URL) return null;
|
||||
const rawUrl = new URL(GITHUB_RUNTIME_STATE_URL);
|
||||
rawUrl.searchParams.set("runtime", `${Date.now()}-${Math.random().toString(36).slice(2)}`);
|
||||
const rawResponse = await fetch(rawUrl, {
|
||||
cache: "no-store",
|
||||
headers: { Accept: "application/json", "Cache-Control": "no-cache" },
|
||||
signal: controller.signal,
|
||||
});
|
||||
if (response.status === 404) return null;
|
||||
if (!response.ok) throw new Error(`GitHub runtime state returned HTTP ${response.status}`);
|
||||
return sanitizeGithubRuntimeState(await response.json());
|
||||
if (rawResponse.status === 404) return null;
|
||||
if (!rawResponse.ok) throw new Error(`GitHub runtime state returned HTTP ${rawResponse.status}`);
|
||||
return sanitizeGithubRuntimeState(await rawResponse.json());
|
||||
} finally {
|
||||
clearTimeout(timeout);
|
||||
}
|
||||
|
||||
+4
-4
@@ -341,7 +341,7 @@ footer{margin-top:34px;padding-top:22px;border-top:1px solid var(--border);color
|
||||
<nav class="topnav">
|
||||
<div class="brand">
|
||||
<div class="logo">🏆</div>
|
||||
<div><div class="brand-name">Polymarket Arena</div><div class="brand-sub">10 agents · 5 core + 5 aggressive</div><div class="build-badge">Adaptive strategy 59 · shock strategy 3 · autonomous runtime 1 · build 90</div></div>
|
||||
<div><div class="brand-name">Polymarket Arena</div><div class="brand-sub">10 agents · 5 core + 5 aggressive</div><div class="build-badge">Adaptive strategy 59 · shock strategy 3 · autonomous runtime 1 · build 91</div></div>
|
||||
</div>
|
||||
<div class="tabs" id="tabs">
|
||||
<button class="tab" data-tab="overview">Overview</button>
|
||||
@@ -363,7 +363,7 @@ footer{margin-top:34px;padding-top:22px;border-top:1px solid var(--border);color
|
||||
<div class="personal-banner" id="personalBanner">
|
||||
<b>Personal research mode.</b> This copy is for your own analysis, paper tracking, and manual trade research only. It does not pool money, onboard investors, custody funds, bypass eligibility rules, or place orders without your manual approval.
|
||||
</div>
|
||||
<div class="live-build-banner"><b>Build 90 active:</b> The public paper agents now have an hourly autonomous runner that continues when every user device is closed. A sanitized agent-only snapshot is written to a separate GitHub runtime branch and becomes the shared read-only fallback while Neon and Blob are unavailable. Empty initialization snapshots are rejected, and the fallback bypasses stale branch caches so phones and computers receive the same latest cycle. Personal accounts, emails, passwords, allocations, and live-money settings never enter that snapshot. The five aggressive agents retain Strategy 3's two-cent-stressed 12-hour shock fades, event deduplication, and forward demotion. Profits are not guaranteed.</div>
|
||||
<div class="live-build-banner"><b>Build 91 active:</b> The public paper agents now have an hourly autonomous runner that continues when every user device is closed. A sanitized agent-only snapshot is written to a separate GitHub runtime branch and becomes the shared read-only fallback while Neon and Blob are unavailable. Empty initialization snapshots are rejected, and the fallback resolves the current branch commit so phones and computers receive the same latest cycle. Personal accounts, emails, passwords, allocations, and live-money settings never enter that snapshot. The five aggressive agents retain Strategy 3's two-cent-stressed 12-hour shock fades, event deduplication, and forward demotion. Profits are not guaranteed.</div>
|
||||
|
||||
<!-- ============ OVERVIEW ============ -->
|
||||
<section class="tabpanel" data-tab="overview">
|
||||
@@ -745,7 +745,7 @@ footer{margin-top:34px;padding-top:22px;border-top:1px solid var(--border);color
|
||||
</section>
|
||||
|
||||
<footer>
|
||||
Build 90 · Adaptive strategy 59 · Shock strategy 3 · Autonomous runtime 1 · Offline runtime 2 · Maker research 3 · Agent learning 3 · Paper trading only · Live prices from Polymarket's public Gamma and CLOB APIs · Not financial advice ·
|
||||
Build 91 · Adaptive strategy 59 · Shock strategy 3 · Autonomous runtime 1 · Offline runtime 2 · Maker research 3 · Agent learning 3 · Paper trading only · Live prices from Polymarket's public Gamma and CLOB APIs · Not financial advice ·
|
||||
<a class="market-link" href="https://github.com/theodore-song/polymarket-analyst" target="_blank" rel="noopener">Source on GitHub</a>
|
||||
</footer>
|
||||
</div>
|
||||
@@ -774,7 +774,7 @@ const POLITICS_TREND_MIN_HOLD_HOURS = 72;
|
||||
const EXIT_CONFIRM_HOURS = 6;
|
||||
const AGENTS_KEY = "pma_agents_v2";
|
||||
const SUG_KEY = "pma_suggestions_v5";
|
||||
const BUILD_VERSION = 90;
|
||||
const BUILD_VERSION = 91;
|
||||
const AGENT_LEARNING_VERSION = 3;
|
||||
const SUGGESTION_ENGINE_VERSION = 59;
|
||||
const MAKER_STRATEGY_VERSION = 3;
|
||||
|
||||
@@ -128,7 +128,7 @@ async function main() {
|
||||
const branch = process.env.RUNTIME_BRANCH || "runtime-state";
|
||||
const pathname = process.env.RUNTIME_STATE_PATH || "runtime/state.json";
|
||||
const arenaUrl = (process.env.ARENA_URL || "https://polymarket-site-eta.vercel.app").replace(/\/$/, "");
|
||||
const expectedBuild = Number(required("EXPECTED_BUILD", "90"));
|
||||
const expectedBuild = Number(required("EXPECTED_BUILD", "91"));
|
||||
await ensureRuntimeBranch(repository, branch);
|
||||
const prior = await readRuntimeFile(repository, branch, pathname);
|
||||
if (prior.snapshot) validateRuntimeSnapshot(prior.snapshot, 0, { allowIncomplete: true });
|
||||
|
||||
@@ -8,7 +8,7 @@ const workflow = fs.readFileSync(new URL("../.github/workflows/autonomous-cycle.
|
||||
const runner = fs.readFileSync(new URL("./run-autonomous-cycle.mjs", import.meta.url), "utf8");
|
||||
const build = Number(index.match(/const BUILD_VERSION = (\d+);/)?.[1]);
|
||||
|
||||
assert.equal(build, 90);
|
||||
assert.equal(build, 91);
|
||||
assert.deepEqual([...ALLOWED_RUNTIME_KEYS].sort(), ["pma_agents_v2", "pma_suggestions_v5"]);
|
||||
assert.match(index, /function collectPublicRuntimeItems\(\)/);
|
||||
assert.match(index, /const PUBLIC_RUNTIME_KEYS=Object\.freeze\(\[AGENTS_KEY,SUG_KEY\]\)/);
|
||||
@@ -17,10 +17,12 @@ assert.match(index, /window\.PMA_AUTOMATION=Object\.freeze/);
|
||||
assert.match(index, /if\(CLOUD_STATE_HEALTH\.read_only\)return false/);
|
||||
assert.match(api, /runtime-state\/runtime\/state\.json/);
|
||||
assert.match(api, /sanitizeGithubRuntimeState/);
|
||||
assert.match(api, /url\.searchParams\.set\("runtime", `\$\{Date\.now\(\)\}/);
|
||||
assert.match(api, /api\.github\.com\/repos\/theodore-song\/polymarket-analyst\/contents\/runtime\/state\.json/);
|
||||
assert.match(api, /Buffer\.from\(file\.content/);
|
||||
assert.match(api, /searchParams\.set\("runtime", `\$\{Date\.now\(\)\}/);
|
||||
assert.match(workflow, /cron: "7 \* \* \* \*"/);
|
||||
assert.match(workflow, /contents: write/);
|
||||
assert.match(workflow, /EXPECTED_BUILD: "90"/);
|
||||
assert.match(workflow, /EXPECTED_BUILD: "91"/);
|
||||
assert.match(runner, /MAX_STATE_BYTES = 900_000/);
|
||||
|
||||
const agentIds = ["value", "momentum", "favorite", "longshot", "diversifier", "catalyst", "reversal", "breakout", "tailalpha", "conviction"];
|
||||
|
||||
Reference in New Issue
Block a user