@tryvira/sdk 0.1.25 → 0.1.27
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 +105 -49
- package/dist/index.js +6 -1
- package/dist/js-client.d.ts +3 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,94 +1,150 @@
|
|
|
1
1
|
# @tryvira/sdk
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
Typed JavaScript/TypeScript client for Vira's scoped control and runtime APIs.
|
|
3
|
+
The official JavaScript and TypeScript client for Vira. Use it to connect an AI
|
|
4
|
+
application, record observations, author governed behavior, evaluate changes, release
|
|
5
|
+
approved behavior, and resolve it at runtime.
|
|
7
6
|
|
|
8
7
|
## Install
|
|
9
8
|
|
|
10
9
|
```bash
|
|
11
|
-
npm install @tryvira/sdk
|
|
10
|
+
npm install @tryvira/sdk@0.1.26
|
|
12
11
|
```
|
|
13
12
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
13
|
+
Configure the organization, project, and environment for every request. Keep the API
|
|
14
|
+
key server-side.
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
export VIRA_CONTROL_URL="https://api.tryvira.xyz"
|
|
18
|
+
export VIRA_API_KEY="<your-vira-api-key>"
|
|
19
|
+
export VIRA_ORGANIZATION_ID="<organization-id>"
|
|
20
|
+
export VIRA_PROJECT_ID="<project-id>"
|
|
21
|
+
export VIRA_ENVIRONMENT_ID="<environment-id>"
|
|
22
|
+
```
|
|
17
23
|
|
|
18
24
|
## Connect and record an observation
|
|
19
25
|
|
|
20
26
|
```ts
|
|
21
|
-
import {
|
|
27
|
+
import { randomUUID } from "node:crypto";
|
|
28
|
+
import { ViraClient } from "@tryvira/sdk";
|
|
29
|
+
|
|
30
|
+
const scope = {
|
|
31
|
+
organizationId: process.env.VIRA_ORGANIZATION_ID!,
|
|
32
|
+
projectId: process.env.VIRA_PROJECT_ID!,
|
|
33
|
+
environmentId: process.env.VIRA_ENVIRONMENT_ID!,
|
|
34
|
+
};
|
|
22
35
|
|
|
23
36
|
const vira = new ViraClient({
|
|
24
|
-
baseUrl: process.env.VIRA_CONTROL_URL
|
|
37
|
+
baseUrl: process.env.VIRA_CONTROL_URL!,
|
|
25
38
|
apiKey: process.env.VIRA_API_KEY,
|
|
26
39
|
});
|
|
27
40
|
|
|
28
41
|
const connected = await vira.connectOnce({
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
42
|
+
...scope,
|
|
43
|
+
name: "support-agent",
|
|
44
|
+
systemType: "custom-agent",
|
|
45
|
+
adapterType: "custom-node",
|
|
46
|
+
adapterVersion: "1.0.0",
|
|
47
|
+
idempotencyKey: "connect:support-agent:1",
|
|
32
48
|
});
|
|
33
49
|
|
|
34
|
-
const systemId = String(connected?.body.system?.id);
|
|
35
|
-
const connectionId = String(connected?.body.connection?.id);
|
|
36
50
|
await vira.observe({
|
|
37
|
-
eventId:
|
|
38
|
-
eventType:
|
|
39
|
-
aiSystemId:
|
|
40
|
-
connectionId,
|
|
41
|
-
payload: {
|
|
42
|
-
}, { idempotencyKey: `
|
|
51
|
+
eventId: randomUUID(),
|
|
52
|
+
eventType: "model.response",
|
|
53
|
+
aiSystemId: String(connected.body.system.id),
|
|
54
|
+
connectionId: String(connected.body.connection.id),
|
|
55
|
+
payload: { task: "billing question", outcome: "completed" },
|
|
56
|
+
}, { idempotencyKey: `observation:${randomUUID()}` });
|
|
43
57
|
```
|
|
44
58
|
|
|
45
|
-
|
|
59
|
+
`connectOnce` is idempotent when the same identity and idempotency key are retried.
|
|
60
|
+
Observations are evidence for authoring and evaluation; they do not grant runtime
|
|
61
|
+
authority.
|
|
62
|
+
|
|
63
|
+
## Resolve behavior at runtime
|
|
46
64
|
|
|
47
|
-
Semantic resolution
|
|
48
|
-
boundary and
|
|
65
|
+
Semantic resolution helps select a candidate. Runtime resolution is the enforcing
|
|
66
|
+
boundary and checks scope, policy, release state, and the requested behavior identity.
|
|
49
67
|
|
|
50
68
|
```ts
|
|
51
69
|
const semantic = await vira.resolveSemantic({
|
|
52
|
-
input:
|
|
53
|
-
profile: { domain:
|
|
70
|
+
input: "Answer a customer billing question",
|
|
71
|
+
profile: { domain: "support" },
|
|
54
72
|
});
|
|
55
73
|
|
|
56
74
|
const runtime = await vira.resolveRuntime({
|
|
57
|
-
behaviorPoint:
|
|
58
|
-
executionBoundary:
|
|
59
|
-
idempotencyKey:
|
|
75
|
+
behaviorPoint: "support.answer_billing",
|
|
76
|
+
executionBoundary: scope,
|
|
77
|
+
idempotencyKey: "runtime:billing:request-001",
|
|
60
78
|
});
|
|
79
|
+
|
|
80
|
+
if (runtime.body.decision !== "ALLOW") {
|
|
81
|
+
throw new Error(`Vira denied runtime resolution: ${runtime.body.reason ?? "unknown"}`);
|
|
82
|
+
}
|
|
61
83
|
```
|
|
62
84
|
|
|
63
|
-
Do not treat a semantic
|
|
64
|
-
|
|
85
|
+
Do not treat a semantic match, a score, or a strategy activation as a release. The
|
|
86
|
+
server may deny or abstain when no eligible immutable revision exists.
|
|
65
87
|
|
|
66
|
-
##
|
|
88
|
+
## Create and release a Pack
|
|
67
89
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
90
|
+
Use a Pack when a Task, Behavior Point, Program, Strategy, signals, and evaluation
|
|
91
|
+
material should move together. A Pack is a candidate until it has been evaluated,
|
|
92
|
+
approved, and released.
|
|
71
93
|
|
|
72
94
|
```ts
|
|
73
|
-
const packs = await vira.listPacks();
|
|
74
95
|
const imported = await vira.importPack({
|
|
75
|
-
manifest: { id:
|
|
76
|
-
objects: {
|
|
77
|
-
|
|
96
|
+
manifest: { id: "support.billing", name: "Billing support behavior", version: "1.0.0" },
|
|
97
|
+
objects: {
|
|
98
|
+
semanticTasks: [{
|
|
99
|
+
taskKey: "support.answer_billing",
|
|
100
|
+
description: "Answer billing questions using available account evidence",
|
|
101
|
+
examples: ["Why was I charged twice?"],
|
|
102
|
+
}],
|
|
103
|
+
behaviorPoints: [{
|
|
104
|
+
key: "support.answer_billing",
|
|
105
|
+
taskKey: "support.answer_billing",
|
|
106
|
+
requirement: "Be accurate, cite evidence, and ask for missing account context",
|
|
107
|
+
}],
|
|
108
|
+
},
|
|
109
|
+
idempotencyKey: "pack:import:support.billing:1.0.0",
|
|
78
110
|
});
|
|
79
|
-
console.log(packs?.body, imported?.body);
|
|
80
111
|
|
|
81
|
-
const
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
112
|
+
const packId = String(imported.body.pack.id);
|
|
113
|
+
await vira.installPack(packId, { variables: {} });
|
|
114
|
+
const evaluation = await vira.evaluatePack(packId, {
|
|
115
|
+
candidateExecutionRequired: true,
|
|
116
|
+
rubric: {
|
|
117
|
+
taskCorrectness: 1,
|
|
118
|
+
behaviorCompliance: 1,
|
|
119
|
+
groundedness: 1,
|
|
120
|
+
safetyAuthority: 1,
|
|
121
|
+
usefulSpecificity: 1,
|
|
122
|
+
},
|
|
123
|
+
idempotencyKey: "pack:evaluate:support.billing:1.0.0",
|
|
85
124
|
});
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
await vira.evaluatePack('pack-id', { evaluationId: 'evaluation-id' });
|
|
125
|
+
if (evaluation.body.passed !== true) throw new Error("Candidate evaluation failed");
|
|
126
|
+
await vira.approvePack(packId);
|
|
127
|
+
await vira.releasePack(packId);
|
|
90
128
|
```
|
|
91
129
|
|
|
130
|
+
Never submit a client-created `passed`, `score`, or receipt as release evidence. Vira
|
|
131
|
+
binds evaluation to the materialized Pack digest and immutable release identity. Use
|
|
132
|
+
`previewPackUpgrade` before changing an installed Pack so conflicts and preserved
|
|
133
|
+
overrides are visible first.
|
|
134
|
+
|
|
135
|
+
## Errors and retries
|
|
136
|
+
|
|
137
|
+
- Send an idempotency key with mutations.
|
|
138
|
+
- Treat `401`/`403` as credential or scope errors; do not retry blindly.
|
|
139
|
+
- Treat a runtime deny or abstain as a governed decision, not permission to bypass Vira.
|
|
140
|
+
- Persist request IDs and receipts with application logs for support and audit.
|
|
141
|
+
|
|
92
142
|
## Documentation
|
|
93
143
|
|
|
94
|
-
|
|
144
|
+
- [Developer guide](https://github.com/hrpering/tryvira/blob/main/docs/developer-guide.md)
|
|
145
|
+
- [Pack authoring](https://github.com/hrpering/tryvira/blob/main/docs/packs.md)
|
|
146
|
+
- [Runtime and release](https://github.com/hrpering/tryvira/blob/main/docs/runtime.md)
|
|
147
|
+
- [API reference](https://github.com/hrpering/tryvira/blob/main/docs/reference/api.md)
|
|
148
|
+
|
|
149
|
+
The client library is MIT licensed. The hosted Vira service and backend are governed
|
|
150
|
+
separately.
|
package/dist/index.js
CHANGED
|
@@ -653,7 +653,12 @@ var ViraClient = class {
|
|
|
653
653
|
}
|
|
654
654
|
createTeachAnalysis(evidenceIds, options = {}) {
|
|
655
655
|
if (!Array.isArray(evidenceIds) || evidenceIds.length < 1) throw new Error("SDK_TEACH_ANALYSIS_EVIDENCE_REQUIRED");
|
|
656
|
-
|
|
656
|
+
const body = { evidenceIds: [...evidenceIds] };
|
|
657
|
+
if (options.analysisId) body.analysisId = options.analysisId;
|
|
658
|
+
if (options.controlPointId) body.controlPointId = options.controlPointId;
|
|
659
|
+
if (options.summary) body.summary = options.summary;
|
|
660
|
+
const requestKey = JSON.stringify([evidenceIds, options.analysisId ?? "", options.controlPointId ?? "", options.summary ?? ""]);
|
|
661
|
+
return this.request({ method: "POST", path: "/v1/teach/analyses", body }, { idempotencyKey: options.idempotencyKey ?? `sdk:teach:analysis:${requestKey}` });
|
|
657
662
|
}
|
|
658
663
|
getTeachAnalysis(analysisId) {
|
|
659
664
|
required(analysisId, "SDK_TEACH_ANALYSIS_ID_REQUIRED");
|
package/dist/js-client.d.ts
CHANGED
|
@@ -382,6 +382,9 @@ export declare class ViraClient {
|
|
|
382
382
|
}): Promise<ViraResponse<ClientBody> | null>;
|
|
383
383
|
createTeachAnalysis(evidenceIds: readonly string[], options?: {
|
|
384
384
|
idempotencyKey?: string;
|
|
385
|
+
analysisId?: string;
|
|
386
|
+
controlPointId?: string;
|
|
387
|
+
summary?: string;
|
|
385
388
|
}): Promise<ViraResponse<ClientBody> | null>;
|
|
386
389
|
getTeachAnalysis(analysisId: string): Promise<ViraResponse<ClientBody> | null>;
|
|
387
390
|
createTeachProposal(input: ClientBody, options?: {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tryvira/sdk",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.27",
|
|
4
4
|
"description": "Typed Vira SDK for connect-once, observation and governed runtime execution.",
|
|
5
5
|
"keywords": ["vira", "ai-governance", "ai-runtime", "semantic-routing"],
|
|
6
6
|
"engines": {"node": ">=20"},
|