7a6852e33a1256901ad8cc476435f0f430023fa0
7 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
f0173440e4 |
Put Piggy on Prime Agent, and let it write to the book
Piggy was a hand-rolled OpenAI tool loop. It is now a Prime Agent session — Prime Intellect's own harness, embedded as a Node library — answering from PIG's tools and, for the first time, able to put information into the CRM rather than only read it out. The harness is a coding agent, so the first job was taking the coding agent away from it. `noTools: 'all'` plus an explicit allowlist leaves the model with PIG's ten `pig_*` tools and no bash, no filesystem, no IPython. That holds under attack: a hostile extension, a skill and a settings file planted in the agent's own directory, then `setActiveToolsByName` called with every built-in, still leaves ten tools, all ours. Both lines are load-bearing — `noTools` alone registers nothing, and the allowlist is what admits our own. Writing is gated rather than assumed. A change is proposed, not made: the tool returns a description, the transcript renders a diff card, and nothing reaches the database until someone presses Apply. Contracts, commitments, allocations and compliance always stop for a human whatever the mode. Every write runs through `executeMutation` as the calling user, so their capabilities and the audit trail apply exactly as they would to a human's. Four things about the SDK are wrong in its own documentation and cost a debugging cycle each: models.json does not resolve an env var name for `apiKey`, it sends the literal string; there is no built-in prime-inference provider in 0.84.1; a ResourceLoader you pass in is never reloaded for you; and the stock system prompt is a coding-assistant prompt that must be replaced — but replacing it also silently removes the tool list, because the harness only renders that section when it owns the prompt. AGENTS.md records all four. The expensive one was thinking level. The harness defaults to `medium`, and nemotron spent an entire 4,096-token budget reasoning and returned an empty answer. `low` was worse; `off` omits the parameter so the endpoint's default wins. An explicit `reasoning_effort: none` via `thinkingLevelMap` took a turn from 6,195 output tokens to 149. And a turn is now bounded. The harness loop is `while (true)` with no iteration cap; a runaway on a frontier model would have eaten the credit it is supposed to report on. Ceilings on model calls and tokens, enforced both through the harness hook and independently from the event stream, plus a per-user daily spend limit — and the ledger now records spend on turns that fail, which it previously discarded. Signing in lands on /piggy, which is a workspace: conversations down one side, the agent in the middle, what it did and what it cost beside it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
99d165b5e5 |
Rebuild Piggy's interface, and give the demo book a business to describe
Piggy answered in raw markdown, threw away every tool result it streamed, and fought the reader's scroll on every token. The three surfaces that made it worth having — what it read, how it reasoned, what it cost — were all on the wire and none of them reached the screen. The transcript is now composed of five parts under components/piggy: answers render through streamdown, the container sticks to the bottom without pinning the reader there, tool steps say what they read and link to the record, and each turn carries its model and token count. Three lifecycle bugs went with them: Stop left a permanent spinner, a truncated stream was indistinguishable from thinking, and a failed send destroyed the message it failed to send. Underneath, the inference path grew timeouts, jittered retries on 429 and 5xx, tolerance of the malformed frames a 30B model emits, and an agent_runs row per turn so chat spend is observable. The system prompt now states that a field ending in Cents is cents — without it nemotron renders costPerGpuHourCents: 189 as "$189 per GPU-hour", which is a 100x error on the most scrutinised number in the room. The demo book was arithmetically incoherent: every deal's value contradicted its own allocation revenue by up to 3.6x, nothing had ever closed, no customer had any paper, and the marketplace was empty. Deal value is now derived from the allocation, the book clears 5.3% across five blocks with one deliberately underwater, and the renewal, compliance and agent-provenance machinery finally has rows to act on. A --clear that deleted every obligation, SLA term and capacity request in the database regardless of origin is scoped to the demo's own ids. Around that: accounts have a detail page, ⌘K searches the book, Settings can mint the API keys it always claimed to, and deploy.sh actually ships the agent instead of silently skipping its compose profile. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
76e3caa1cb |
Drop the Comp AI CRM acknowledgement
Nothing in PIG derives from that repository. The fact model, the leased agent task queue and the `agentBrief` field are our own designs, and MIT's attribution condition reaches copied source, not ideas — so the credit was a courtesy that misstated where this code came from. The one line worth keeping was never a credit: AGENTS.md's rule against lifting component files out of somebody else's repo. It is restated generically, and the shadcn-from-upstream guidance stays. Buzz keeps its NOTICE entry. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
13dec6b4b8 |
Rebuild the shell, add Calendar and Learn, and govern reads
Seven parallel agents and an adversarial verification pass. The three things worth knowing before reading the diff: RBAC WAS ALREADY BUILT. docs/build-plan.md marks F2 and F3 outstanding and is stale — packages/core/src/permissions.ts and lib/mutation.ts shipped long ago. So this does not rebuild them; it closes the gaps an audit found. The big one is that reads were entirely ungoverned: every GET was "any authenticated member", so a junior demand rep and a research contractor could both pull per-block supplier cost and break-even prices from /api/capacity/margin, and every contract's negotiated terms. For a company whose margin is the business, that was the hole that mattered. Adds book:read / economics:read / team:read, a readGuard middleware, and a `viewer` role below member. THE BUTTON AND THE 403 DISAGREED — the exact thing F3 said must never happen. Contracts.tsx never called can() at all, so its save button was always enabled against a server requiring contract:sign; Capacity.tsx gated commitment creation on deal:write/demand while the server wanted commitment:write/supply. POST /api/activities was the one write bypassing executeMutation: no capability check, and any member could mutate accounts.lastActivityAt as a side effect. It is now a proper mutation() behind activity:write. The shell becomes three panes — a collapsible shadcn sidebar with an account switcher on the Piggy accent, a header with real search, and Piggy docked to the right, page-aware and persistent across navigation. The phone keeps its bottom tab bar, which is the thing this product already beat trycompai/crm on, and gains the sidebar as a sheet. Calendar is a projection over thirteen dated sources rather than a new table, because a table would duplicate dates that already live on contracts, deals and commitments and would drift — and one ledger answering the question is the whole argument. It surfaces export_authorizations and compliance_artifacts, which had indexed expires_at columns, schema comments saying they must be alerted on, and no read endpoint or UI anywhere. Learn carries two tracks. Concepts are members-only; the platform track can be opened with a share code by someone with no account. The code mints a scoped learn-only token and never a Principal — every route here resolves a principal and then checks capabilities, so a principal-minting code would be one missing check away from leaking the book. "Only platform-track rows may be code-visible" is a database CHECK constraint as well as a write-path rule, and a test asserts a valid learn token still gets 401 on /api/dashboard, /api/accounts and /api/contracts — the same invariant scripts/deploy.sh refuses to ship without. CD becomes tag-to-ship. CI publishes an image to the Gitea registry on a release-* tag and cloud-2 pulls it, so no credential on the shared runner can execute anything on production — by construction rather than by policy. Both halves of deploy.sh's original rule survive: nothing on the runner reaches the host, and a human still decides when it ships. deploy.sh gains a rollback and a public-origin check, and PIG_IMAGE now reaches compose through `sudo env`, without which sudo's env_reset silently resolved every release to pig:local. Tests 141 -> 261. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
cf3117e458 |
Record verified Prime Intellect API facts, and log a real pricing bug
CI / verify (push) Successful in 1m33s
The token was found on cloud-1 after all, in a Claude memory note. Verifying its claims against the live API turned up a defect in code already shipped. **prices.onDemand is the total for the whole node, not per-GPU.** Confirmed: datacrunch lists 1x A100 at 1.79 and 2x A100 at 3.58, and gpuMemory scales the same way (640 for 8x 80GB). packages/prime/src/map.ts stores both as if they were per-GPU, so an 8-GPU node reads eight times too expensive. It would have silently poisoned inventory search, the max-price filter and every margin comparison against bought capacity — and nobody would have noticed, because the numbers still look plausible. Logged rather than fixed, per the instruction to hold; it needs a regression test built from the real 1x/2x pair. **Inference is a different host.** api.primeintellect.ai is compute and pods; inference is api.pinference.ai/api/v1, OpenAI-compatible. PIG's config knows only the first, so A4 and A13 need both. **Piggy's default model** is nvidia/nemotron-3-nano-30b-a3b, and the important detail is that it is a hybrid reasoning model which thinks aloud by default and truncates under a tight max_tokens. `reasoning_effort: "none"` gives ~1s terse output for tool use and extraction, which is what Piggy does nearly all of the time. One claim did NOT reproduce: the note warns of Cloudflare 403ing non-browser user-agents, but PIG's own UA and curl's both returned 200. Recorded as history in case a 403 ever appears. Also logged: the key is a broad, never-expiring credential sitting in plaintext in a memory markdown file. PIG's sync should hold a separate narrower key scoped to availability reads. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
3398345109 |
Plan: add RBAC, capacity tiers, imports, admin settings; expand contracts
CI / verify (push) Successful in 2m36s
Six additions, and one promoted to foundation. RBAC becomes a Wave 0 task rather than something absorbed into each CRUD track. Authorization today stops at "is a member", and eight parallel write tracks plus a bulk-import feature are about to land. Import especially: one bad column mapping can rewrite thousands of records, so it must not ship before there is a real answer to who may run it. Suggested default is team leads and platform admins only — easy to loosen later, unpleasant to tighten. A government/sovereign capacity tier joins secure and community. It is a schema change, so it is cheaper before the tables carry real data. Matching must never satisfy a government requirement with community capacity, and the tier interacts with the export-control predicate already modelled in compliance.ts. Imports are split so the work is reusable: a CSV/Excel framework carrying the upload, mapping, dry-run preview and idempotent commit, with Notion and Google Sheets as thin OAuth front-ends onto the same mapping step. Notion databases are tables with typed properties, so treating them as a separate importer would duplicate the hard part. Admin settings gains Piggy's model selection, defaulting to a Nemotron model on Prime Intellect inference, with the endpoint configurable so an on-prem install can point at the customer's own. Contracts is expanded from "surface the schema" to the full field set — the hierarchy with order-form-beats-MSA precedence, negotiated SLA terms including fee abatement and its trigger, spare-pool scope, maintenance classes and the reasonable-endeavours carve-out, plus take-or-pay and termination tier. Written as a first draft to be corrected by someone who negotiates these for a living. Also records three open questions, including that the Prime Intellect API token could not be found on cloud-1 — searched ~/.prime, ~/.config/prime, /opt and /etc. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
e4698e4d0c |
Add a build plan, informed by reading Comp AI CRM properly
CI / verify (push) Successful in 1m32s
Cloned trycompai/crm (MIT) and inventoried it rather than assuming. Three findings shaped the plan. Their component library is far deeper: 68 primitives to our 9, including data-table, command, sheet, drawer, combobox, chart, and a set of agent-chat components that map almost exactly onto what Piggy needs. Their SourcedValue/Provenance pattern is worth adopting outright — a dotted underline on any agent-derived value with a tooltip carrying the claim, the reasons, when it was observed and the source URL. PIG already stores all of that in `facts` and surfaces none of it. But we are ahead of them on mobile, not behind. Measured across both repos: 211 responsive utilities across their 329 tsx files (0.6 per file) against 58 across our 16 (3.6 per file); zero safe-area handling to our five; no drawer or sheet used for navigation, no viewport-fit. Their app is effectively desktop-only. So the plan takes depth from them, not mobile behaviour. The plan also says not to copy their component files. Most are shadcn/ui originals — MIT, and designed to be installed from upstream where they are canonical and current. Borrow the compositions as ideas; the debt is already credited in NOTICE. Structured into waves with real dependency edges so the work can be handed to several agents without collision. Two foundation tasks must land alone first (the primitive set, and the API write-path convention) because eight parallel CRUD tracks would otherwise each invent their own. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |