@felspar/sdk 0.3.0 → 0.4.1
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/README.md +25 -22
- package/dist/chunks/{chunk-3YVYBD4H.js → chunk-PYLLH47S.js} +1771 -743
- package/dist/chunks/{chunk-2RV7RPXW.js → chunk-SQ62T4AA.js} +3 -2
- package/dist/chunks/{chunk-7HN5KUTJ.js → chunk-WAMWMJYP.js} +1 -1
- package/dist/draft-action-gate-claude.js +2 -2
- package/dist/draft-action-gate-eve.js +3 -3
- package/dist/draft-action-gate-openai.js +2 -2
- package/dist/draft-action-gate.js +2 -2
- package/dist/draft-hosted-client.js +1 -1
- package/dist/eve.js +3 -3
- package/dist/types/draft-hosted-client.d.ts +630 -7
- package/package.json +1 -6
- package/bin/felspar-sdk.mjs +0 -10
- package/bin/skill.mjs +0 -33
- package/skills/felspar/SKILL.md +0 -134
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Felspar is a shared, versioned decision system for enterprise agents. A company's approved meaning, the evidence a decision needs and the decision itself travel together in a released Decision Pack. Agents ask Felspar for a decision, get a receipt they can verify, and act only on what Felspar decided.
|
|
4
4
|
|
|
5
|
-
This package connects an agent to Felspar: an [Eve](https://github.com/vercel/eve) connection in two lines, a TypeScript client for the hosted Felspar API, an action gate that keeps an agent's tools from acting without a verified Felspar decision
|
|
5
|
+
This package connects an agent to Felspar: an [Eve](https://github.com/vercel/eve) connection in two lines, a TypeScript client for the hosted Felspar API, and an action gate that keeps an agent's tools from acting without a verified Felspar decision. It runs on Node.js 24 or later, and its only dependency is `zod`. The SDK is a transport client: decisions and policy stay with the Felspar service and the released pack, and the SDK does not reimplement them.
|
|
6
6
|
|
|
7
7
|
The modules under `draft/` may change between minor versions while the API settles, before 1.0.
|
|
8
8
|
|
|
@@ -22,7 +22,7 @@ import { felsparConnection } from "@felspar/sdk/eve";
|
|
|
22
22
|
export default defineMcpClientConnection(felsparConnection());
|
|
23
23
|
```
|
|
24
24
|
|
|
25
|
-
The agent gets Felspar's `list_jobs`, `get_job_requirements`, `get_job_decision` and `check_output` tools and nothing else. The key is the agent's own, created on the Felspar web page (Workspace →
|
|
25
|
+
The agent gets Felspar's `list_jobs`, `get_job_requirements`, `get_job_decision` and `check_output` tools and nothing else. The key is the agent's own, created on the Felspar web page (Workspace → Company agents) and read from `FELSPAR_AGENT_KEY` when Eve connects; the endpoint is `FELSPAR_MCP_URL`, or production. Pass `{ url, agentKey, description }` to override them. The tools carry the method: `get_job_requirements` says what to gather and how, and each result says what to do next, so the agent needs no Felspar skill or prompt of its own.
|
|
26
26
|
|
|
27
27
|
Over MCP, `get_job_requirements` and `get_job_decision` answer compactly by default. The brief's `input` lists the arguments and a short `facts` example from the job's own questions. The decision keeps what the agent acts on, plus `executionObjectId`, the full `receipt`, the `context` capsule and `explanation.evidenceFreshUntil`, which is what the action gate records and verifies. `detail: "full"` returns the REST brief or result unchanged. The agent sends no execution ID: calling `get_job_decision` again with the same arguments within the same hour returns the decision already made, and `blocked` means that first call is still running. See [MCP tools](https://docs.felspar.ai/reference/mcp-tools).
|
|
28
28
|
|
|
@@ -36,18 +36,23 @@ const felspar = createHostedFelsparClient({
|
|
|
36
36
|
agentKey: process.env.FELSPAR_AGENT_KEY,
|
|
37
37
|
});
|
|
38
38
|
|
|
39
|
-
//
|
|
40
|
-
const
|
|
39
|
+
// The jobs this agent key may run, by ID.
|
|
40
|
+
const { jobs } = await felspar.listJobs();
|
|
41
|
+
|
|
42
|
+
// What the job needs (questions, evidence rules, outcomes and their outputs),
|
|
43
|
+
// on the release Felspar runs for this key now.
|
|
44
|
+
const job = await felspar.describeCurrentJob("route-support-ticket");
|
|
45
|
+
const releaseId = job.release.releaseId;
|
|
41
46
|
|
|
42
47
|
// Facts in, decision out. The release pin comes from the job description.
|
|
43
48
|
const response = await felspar.resolveFacts(releaseId, {
|
|
44
|
-
jobId: "
|
|
49
|
+
jobId: "route-support-ticket",
|
|
45
50
|
executionId: crypto.randomUUID(),
|
|
46
|
-
entityId: "
|
|
51
|
+
entityId: "48213",
|
|
47
52
|
facts: {
|
|
48
|
-
|
|
49
|
-
text: "
|
|
50
|
-
source: { class: "
|
|
53
|
+
request_type: {
|
|
54
|
+
text: "I was charged twice for my March invoice.",
|
|
55
|
+
source: { class: "ticket-thread", id: "48213", observedAt: new Date().toISOString() },
|
|
51
56
|
},
|
|
52
57
|
},
|
|
53
58
|
});
|
|
@@ -55,14 +60,19 @@ const response = await felspar.resolveFacts(releaseId, {
|
|
|
55
60
|
if (response.status === "ready") {
|
|
56
61
|
console.log(response.result?.outcome, response.result?.receipt);
|
|
57
62
|
}
|
|
58
|
-
|
|
59
|
-
// The jobs this agent key may run, by ID.
|
|
60
|
-
const { jobs } = await felspar.listJobs();
|
|
61
63
|
```
|
|
62
64
|
|
|
65
|
+
`describeJob(releaseId, jobId)` describes a release you already know, such as one you pinned.
|
|
66
|
+
|
|
67
|
+
Facts can come straight from a system of record, with no agent in between: send each question's evidence as the source's own words (`text`, such as a ticket's body or an account record's "Plan: Business (monthly)") with where it came from (`source.class`, `source.id`, `source.observedAt`). Felspar classifies those words for answer-choice and yes/no questions; a bare label such as `{ value: "business" }` is refused with `label_needs_mapping`, because the released question decides what the words mean. Number and date questions take a typed `{ value }` (a date as `YYYY-MM-DD`). Only the job's own question keys are accepted (`unknown_question` otherwise).
|
|
68
|
+
|
|
69
|
+
Words a person gave the agent (a line from a call, a message) are evidence too: send them as given with `source: { class, manual: true, locator }`, naming in `locator` the source they came from, and no `id` or `observedAt`; Felspar stamps the time it received them, and the result and its receipt list them under `manualFacts`. A job whose description carries `manualFacts: { allowed: false }` refuses them (`manual_facts_refused`): quote the source record itself.
|
|
70
|
+
|
|
71
|
+
`verifyReceipt(executionObjectId, { receipt, expectedReceiptDigest, deliveredCapsule })` asks Felspar to replay a decision and compare its receipt, and `checkOutput(job, { executionId, text, output? })` checks text written for one of your decisions (`readOutputCheck(job, checkId)` reads a check back).
|
|
72
|
+
|
|
63
73
|
How a case is identified comes from the job's description (`identity`): send `entityId` for the record's own ID (`provided`), `identity` field values (`fields`), or nothing (`content`, and the first decision of an `issued` job). The result's `case` gives the case's `id` and `mode`; send `case.id` as `entityId` for every later decision on the same case. Results are typed (`FelsparJobResult`): `case`, `subject` with its `related` records, `escalation` (`id`, `trigger`, `why`) and `missing` for a gap.
|
|
64
74
|
|
|
65
|
-
A refused request throws `FelsparRequestError` with the HTTP `status` and the service's `refusal` (its `error` code, where there is one a `fix`, and any `escalation` it names, such as for `attempt_limit_reached`).
|
|
75
|
+
A refused request throws `FelsparRequestError` with the HTTP `status` and the service's `refusal` (its `error` code, where there is one a `fix` and a `recovery` of `fix_input`, `retry` or `escalate`, and any `escalation` it names, such as for `attempt_limit_reached`).
|
|
66
76
|
|
|
67
77
|
## Action gate
|
|
68
78
|
|
|
@@ -150,16 +160,9 @@ Outside an agent framework, `checkAction({ rules, toolName, input, decisions, ve
|
|
|
150
160
|
|
|
151
161
|
A Felspar receipt records what Felspar decided from the evidence it was given. It is not a factual, legal or security certification, and a passed output check means the text follows the released rules, not that it is true or approved to send.
|
|
152
162
|
|
|
153
|
-
##
|
|
154
|
-
|
|
155
|
-
The package ships the skill (its version matches the package's) that teaches an agent the method for any Felspar job: get the requirements, gather exact evidence, get the decision, write and check what the decision asks for, and escalate with the company's next step.
|
|
156
|
-
|
|
157
|
-
```bash
|
|
158
|
-
npx @felspar/sdk skill # writes agent/skills/felspar/SKILL.md
|
|
159
|
-
npx @felspar/sdk skill .claude --force
|
|
160
|
-
```
|
|
163
|
+
## Examples
|
|
161
164
|
|
|
162
|
-
|
|
165
|
+
[felspar-examples](https://github.com/orchidautomation/felspar-examples) has complete projects: an Eve agent, the same agent with email drafts behind the action gate, and a script that gets a decision with no agent.
|
|
163
166
|
|
|
164
167
|
## Documentation
|
|
165
168
|
|