@conscience-technology/nora-sdk
v0.0.1
Published
Nora platform client. Agents are built in Nora (MCP/CLI/UI); here you call them, look inside them, and feed results back.
Readme
nora-sdk
Nora platform client. Agents are built in Nora (MCP/CLI/UI), and here you call them, look inside them, and feed results back. It never edits definitions: that path is MCP/CLI/UI → approve → version, one human gate.
Server-side only. It carries a server credential (a PAT or a trigger secret), so it throws if initialized in a browser — proxy any end-user-facing execution through your own server.
Install
npm install @conscience-technology/nora-sdkTwo credentials
| Credential | Used for | Scope |
|---|---|---|
| trigger secret (per flow) | flows.run, signals.report on traces it created | that one flow |
| PAT nora_pat_… + scopes | resolve, improvements.*, simulations.* | the workspace |
PAT scopes: read (resolve / improvements list) · content (memory/knowledge writes) · simulate (billed) · approve (ships changes). A read token cannot approve.
Use
import { createClient, NoraAuthError } from "@conscience-technology/nora-sdk";
const nora = createClient({
tenant: "t_...",
token: process.env.NORA_PAT, // management
triggerSecret: process.env.NORA_TRIGGER_SECRET, // execution
});
// Run a flow (trigger secret). A failed run still returns traceId + partial output.
const r = await nora.flows.run("support", "my ticket text");
console.log(r.traceId, r.status, r.outputs, r.notices);
// Look inside: the effective definition (PAT read scope).
const def = await nora.resolve("support");
// Feedback on the answer itself (👍/👎 + optional correction).
await nora.feedback(r.traceId, { rating: "dislike", comment: "wrong coverage", correction: { after: "..." } });
// Feed the app's real business outcome back into the loop (separate from the rating above).
await nora.signals.report(r.traceId, { outcome: "resolved", reason: "user confirmed" });
// Embed the loop: an improvement is a concrete before→after fix the loop proposed
// for a failure cluster (with a measured delta) — NOT the cluster list. Show the
// proposal queue in your admin page and approve there (approve scope).
const queue = await nora.improvements.list();
try {
await nora.improvements.approve("imp_123"); // adopt → deploys a new version
} catch (e) {
if (e instanceof NoraAuthError) console.error("need the approve scope:", e.code);
}Errors
Every failure is a typed NoraError subclass with a stable .code, .traceId, and server-decided .retryable:
NoraError
├─ NoraAuthError auth / scope / subject
├─ NoraRequestError flow / input / scope missing
├─ NoraAccessError memory / knowledge access rule
├─ NoraProviderError upstream LLM provider
└─ NoraPlatformError availability / rate limit / internalTransport and request failures throw. Execution-result outcomes (turn cap, tool failure, needs-review) come back on RunResult with traceId + partial outputs, never as a throw — so you can still read what the run produced.
Logging
Structured and redacted by default (no tokens, secrets, claims, or bodies). Inject your logger and observe internals:
createClient({ tenant, token, logger: pino(), onLog: (e) => metrics.count(e.event) });