Ship v0.1.1–v0.1.5: first-live-run fixes and dashboard viewer
- v0.1.1: config persistence — FileHelper paths made absolute (/media/startos/volumes/main/...); relative paths resolved into the JS runtime's ephemeral cwd so action saves never reached /data - v0.1.2: preJobStopContainers (Configure Grading) — docker-stop resident vLLM containers on the head Spark at job start, no auto-restart - v0.1.3: preflight auth (LiteLLM master_key gates /models), poll-until-loaded, crash fast-fail (restarting counts as dead) - v0.1.4: HF_HUB_OFFLINE/TRANSFORMERS_OFFLINE in airgapped serving (--internal network has no DNS); grader _post timeout 600→1800s for ~3.6 tok/s GB10 generation - v0.1.5: dashboard viewer survives the periodic background refresh; download buttons for deck reports, deck JSON, and SCORECARD.md - .gitignore: .startos/ build workspace, start-technologies/ Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
1d1074b625
commit
91212322c1
@@ -84,6 +84,18 @@ const inputSpec = InputSpec.of({
|
||||
'land in the inbox. Off by default so you trigger grading explicitly.',
|
||||
default: false,
|
||||
}),
|
||||
preJobStopContainers: Value.text({
|
||||
name: 'Stop These Containers Before Grading (optional)',
|
||||
description:
|
||||
'Space- or comma-separated docker container names stopped on the HEAD ' +
|
||||
'Spark at the start of every grading job, so the job gets the GPU to ' +
|
||||
'itself (e.g. an always-on vLLM another service runs). They are NOT ' +
|
||||
'restarted afterwards — the service that owns them reloads its own ' +
|
||||
'models (e.g. the Gazette\'s Fleet job). Empty = stop nothing.',
|
||||
required: false,
|
||||
default: null,
|
||||
placeholder: 'vllm-gemma4-clerk',
|
||||
}),
|
||||
// --- Deterministic-scorer weights (composite = quant 60 + qual 40 - flags) ---
|
||||
profitabilityKpi: Value.number({
|
||||
name: 'Weight: Profitability KPIs',
|
||||
@@ -204,6 +216,7 @@ export const configureGrading = sdk.Action.withInput(
|
||||
adjudicatorPersona: cfg.adjudicatorPersona || undefined,
|
||||
wipeRemoteDocs: cfg.wipeRemoteDocs,
|
||||
autoRunOnDrop: cfg.autoRunOnDrop,
|
||||
preJobStopContainers: cfg.preJobStopContainers || undefined,
|
||||
profitabilityKpi: cfg.weights.profitabilityKpi,
|
||||
otherKpi: cfg.weights.otherKpi,
|
||||
forecastIntegrity: cfg.weights.forecastIntegrity,
|
||||
@@ -228,6 +241,7 @@ export const configureGrading = sdk.Action.withInput(
|
||||
adjudicatorPersona: input.adjudicatorPersona ?? '',
|
||||
wipeRemoteDocs: input.wipeRemoteDocs,
|
||||
autoRunOnDrop: input.autoRunOnDrop,
|
||||
preJobStopContainers: input.preJobStopContainers ?? '',
|
||||
weights: {
|
||||
profitabilityKpi: input.profitabilityKpi,
|
||||
otherKpi: input.otherKpi,
|
||||
|
||||
@@ -172,6 +172,10 @@ export const configShape = z.object({
|
||||
autoRunOnDrop: z.boolean().default(false),
|
||||
// Name of the per-job Docker network created on the head Spark.
|
||||
networkName: z.string().default('boardroom-net'),
|
||||
// Space/comma-separated docker container names stopped on the head Spark at
|
||||
// the start of every job to free GPU memory (e.g. an always-on vLLM another
|
||||
// service runs). NOT restarted afterwards — their owner reloads them.
|
||||
preJobStopContainers: z.string().default(''),
|
||||
|
||||
// --- Portfolio companies ---
|
||||
// The authoritative source of pinned KPI targets and KPI-name aliases. Decks
|
||||
@@ -212,4 +216,11 @@ export const configShape = z.object({
|
||||
|
||||
export type Config = z.infer<typeof configShape>
|
||||
|
||||
export const configFile = FileHelper.json('./config.json', configShape)
|
||||
// Absolute path into the `main` volume (mounted at /media/startos/volumes/main
|
||||
// in the JS runtime, /data in the orchestrator container). A relative path here
|
||||
// resolves against the JS runtime's EPHEMERAL working directory and silently
|
||||
// loses the config on restart.
|
||||
export const configFile = FileHelper.json(
|
||||
'/media/startos/volumes/main/config.json',
|
||||
configShape,
|
||||
)
|
||||
|
||||
@@ -5,9 +5,13 @@ import { FileHelper } from '@start9labs/start-sdk'
|
||||
* `main` volume. Kept out of config.json so it is never returned in plaintext
|
||||
* config reads. The container copies it to a 600 path at runtime.
|
||||
*
|
||||
* Volume path './ssh/id_spark' -> /data/ssh/id_spark inside the container.
|
||||
* Volume path (absolute — a relative path would resolve against the JS
|
||||
* runtime's ephemeral cwd, not the volume) -> /data/ssh/id_spark inside the
|
||||
* orchestrator container.
|
||||
*/
|
||||
export const sshKeyFile = FileHelper.string('./ssh/id_spark')
|
||||
export const sshKeyFile = FileHelper.string(
|
||||
'/media/startos/volumes/main/ssh/id_spark',
|
||||
)
|
||||
|
||||
/**
|
||||
* Optional Hugging Face token (for gated/private model pulls on the Sparks).
|
||||
@@ -15,7 +19,7 @@ export const sshKeyFile = FileHelper.string('./ssh/id_spark')
|
||||
* network mode models are served from a pre-pulled cache, so this is only used
|
||||
* the first time you warm a model (or in local_services mode).
|
||||
*
|
||||
* Volume path './secrets/hf_token' -> /data/secrets/hf_token.
|
||||
* Volume path (absolute, see above) -> /data/secrets/hf_token.
|
||||
*
|
||||
* NOTE: Boardroom Map has NO frontier/cloud key. There is deliberately no Anthropic
|
||||
* key and no Gitea token — the whole point is that confidential documents and
|
||||
|
||||
@@ -1,8 +1,13 @@
|
||||
import { VersionGraph } from '@start9labs/start-sdk'
|
||||
import { v_0_1_0 } from './v_0_1_0'
|
||||
import { v_0_1_1 } from './v_0_1_1'
|
||||
import { v_0_1_2 } from './v_0_1_2'
|
||||
import { v_0_1_3 } from './v_0_1_3'
|
||||
import { v_0_1_4 } from './v_0_1_4'
|
||||
import { v_0_1_5 } from './v_0_1_5'
|
||||
|
||||
/** The current version MUST be the first argument (`current`). */
|
||||
export const versions = VersionGraph.of({
|
||||
current: v_0_1_0,
|
||||
other: [],
|
||||
current: v_0_1_5,
|
||||
other: [v_0_1_4, v_0_1_3, v_0_1_2, v_0_1_1, v_0_1_0],
|
||||
})
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
import { VersionInfo } from '@start9labs/start-sdk'
|
||||
|
||||
/**
|
||||
* Packaging fix. ExVer form `<upstream>:<downstream>` — we track our own
|
||||
* packaging revision since Boardroom Map has no separate upstream semver.
|
||||
*/
|
||||
export const v_0_1_1 = VersionInfo.of({
|
||||
version: '0.1.1:0',
|
||||
releaseNotes:
|
||||
'Fix: persist config.json, the Spark SSH key, and the optional HF token ' +
|
||||
'to the main volume (absolute volume paths in the file models). ' +
|
||||
'Previously the Configure actions wrote to an ephemeral runtime directory, ' +
|
||||
'so the orchestrator never saw /data/config.json and configuration was ' +
|
||||
'lost on restart. Re-run the Configure actions after updating.',
|
||||
migrations: {},
|
||||
})
|
||||
@@ -0,0 +1,15 @@
|
||||
import { VersionInfo } from '@start9labs/start-sdk'
|
||||
|
||||
/**
|
||||
* GPU co-residency support. ExVer form `<upstream>:<downstream>`.
|
||||
*/
|
||||
export const v_0_1_2 = VersionInfo.of({
|
||||
version: '0.1.2:0',
|
||||
releaseNotes:
|
||||
'New "Stop These Containers Before Grading" setting (Configure Grading): ' +
|
||||
'container names listed there are docker-stopped on the head Spark at the ' +
|
||||
'start of every grading job, so the job gets the GPU to itself when ' +
|
||||
'another service keeps an always-on vLLM resident. They are deliberately ' +
|
||||
'not restarted afterwards — the owning service reloads its own models.',
|
||||
migrations: {},
|
||||
})
|
||||
@@ -0,0 +1,13 @@
|
||||
import { VersionInfo } from '@start9labs/start-sdk'
|
||||
|
||||
/** Serving-readiness fix. ExVer form `<upstream>:<downstream>`. */
|
||||
export const v_0_1_3 = VersionInfo.of({
|
||||
version: '0.1.3:0',
|
||||
releaseNotes:
|
||||
'Fix wave preflight: the model-proxy probe now authenticates (the router ' +
|
||||
'requires its master key even on /models) and both the proxy check and the ' +
|
||||
'per-model completion check poll until ready instead of failing on a ' +
|
||||
'single early attempt — a 31B model takes minutes to load into GPU ' +
|
||||
'memory. Crashed containers fail fast with their log tail.',
|
||||
migrations: {},
|
||||
})
|
||||
@@ -0,0 +1,13 @@
|
||||
import { VersionInfo } from '@start9labs/start-sdk'
|
||||
|
||||
/** Air-gapped serving fix. ExVer form `<upstream>:<downstream>`. */
|
||||
export const v_0_1_4 = VersionInfo.of({
|
||||
version: '0.1.4:0',
|
||||
releaseNotes:
|
||||
'Air-gapped mode now serves models with HF_HUB_OFFLINE/TRANSFORMERS_OFFLINE ' +
|
||||
'set: the per-job --internal network has no DNS, so without offline mode ' +
|
||||
'the HF hub client crashed on name resolution even with the model fully ' +
|
||||
'cached. Preflight also treats a crash-looping (restarting) vLLM container ' +
|
||||
'as dead and fails fast with its logs instead of waiting out the timeout.',
|
||||
migrations: {},
|
||||
})
|
||||
@@ -0,0 +1,14 @@
|
||||
import { VersionInfo } from '@start9labs/start-sdk'
|
||||
|
||||
/** Dashboard viewer fixes. ExVer form `<upstream>:<downstream>`. */
|
||||
export const v_0_1_5 = VersionInfo.of({
|
||||
version: '0.1.5:0',
|
||||
releaseNotes:
|
||||
'Dashboard: an open deck report / JSON / scorecard viewer now stays open ' +
|
||||
'across the periodic background refresh (previously it silently closed ' +
|
||||
'within ~20s) — it closes only via its close button or when switching ' +
|
||||
'companies. Added ⬇ download buttons: per-deck report downloads in the ' +
|
||||
'deck-history table, plus a download link in the viewer header for ' +
|
||||
'reports, deck JSON records, and SCORECARD.md.',
|
||||
migrations: {},
|
||||
})
|
||||
Reference in New Issue
Block a user