@punktechnologies/sdk 0.1.0
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/LICENSE +162 -0
- package/README.md +169 -0
- package/dist/index.d.ts +334 -0
- package/dist/index.js +1058 -0
- package/dist/types.d.ts +346 -0
- package/package.json +64 -0
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,346 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @punktechnologies/sdk — local type contracts.
|
|
3
|
+
*
|
|
4
|
+
* These mirror the canonical definitions in `@punk/trace-schema` (the
|
|
5
|
+
* dependency-free contract package every Punk service imports). They are
|
|
6
|
+
* copied here — not imported — so the published SDK has zero dependencies.
|
|
7
|
+
*
|
|
8
|
+
* If a shape changes in `@punk/trace-schema`, update the mirror here.
|
|
9
|
+
* The gateway is the source of truth at runtime; these types describe what
|
|
10
|
+
* its API returns.
|
|
11
|
+
*/
|
|
12
|
+
/** MeshGuard-compatible trust tiers. */
|
|
13
|
+
export type TrustTier = "unverified" | "verified" | "trusted" | "privileged";
|
|
14
|
+
/** Trust lane of a memory/context source (memory quarantine). */
|
|
15
|
+
export type TrustLane = "untrusted" | "observed" | "verified" | "human_approved";
|
|
16
|
+
/**
|
|
17
|
+
* 0 pure computation, 1 read-only external, 2 reversible/idempotent writes,
|
|
18
|
+
* 3 user-visible writes (slack/email/tickets), 4 high-impact (payments,
|
|
19
|
+
* deletion, permissions). Undeclared tools default to level 3 (conservative).
|
|
20
|
+
*/
|
|
21
|
+
export type SideEffectLevel = 0 | 1 | 2 | 3 | 4;
|
|
22
|
+
export type SideEffectStatus = "planned" | "executed" | "suppressed" | "dry_run" | "blocked";
|
|
23
|
+
export interface SideEffectRecord {
|
|
24
|
+
id: string;
|
|
25
|
+
runId: string;
|
|
26
|
+
tenantId: string;
|
|
27
|
+
toolName: string;
|
|
28
|
+
level: SideEffectLevel;
|
|
29
|
+
status: SideEffectStatus;
|
|
30
|
+
idempotencyKey?: string;
|
|
31
|
+
payload?: unknown;
|
|
32
|
+
createdAt: number;
|
|
33
|
+
}
|
|
34
|
+
export type RouteType = "live" | "exact_cache" | "semantic_cache" | "tool_cache" | "som_cache" | "plan_cache" | "artifact" | "hybrid_artifact" | "model_substitution" | "chorus" | "blocked";
|
|
35
|
+
export interface RouteAlternative {
|
|
36
|
+
route: RouteType;
|
|
37
|
+
rejected: string;
|
|
38
|
+
}
|
|
39
|
+
export interface PolicyVerdict {
|
|
40
|
+
decision: "allow" | "deny" | "approval_required";
|
|
41
|
+
policyName?: string;
|
|
42
|
+
ruleIndex?: number;
|
|
43
|
+
reason: string;
|
|
44
|
+
trustTier?: TrustTier;
|
|
45
|
+
sideEffectLevel?: SideEffectLevel;
|
|
46
|
+
}
|
|
47
|
+
/** Every optimized response must be explainable. */
|
|
48
|
+
export interface RouteExplanation {
|
|
49
|
+
route: RouteType;
|
|
50
|
+
reason: string;
|
|
51
|
+
alternatives: RouteAlternative[];
|
|
52
|
+
policy?: PolicyVerdict;
|
|
53
|
+
cache?: {
|
|
54
|
+
type: string;
|
|
55
|
+
hit: boolean;
|
|
56
|
+
key?: string;
|
|
57
|
+
freshness?: "valid" | "stale" | "expired";
|
|
58
|
+
ageMs?: number;
|
|
59
|
+
};
|
|
60
|
+
artifact?: {
|
|
61
|
+
id: string;
|
|
62
|
+
version: number;
|
|
63
|
+
confidence: number;
|
|
64
|
+
shadowed?: boolean;
|
|
65
|
+
};
|
|
66
|
+
pattern?: {
|
|
67
|
+
id: string;
|
|
68
|
+
name: string;
|
|
69
|
+
confidence: number;
|
|
70
|
+
};
|
|
71
|
+
estimatedSavedUsd?: number;
|
|
72
|
+
estimatedSavedMs?: number;
|
|
73
|
+
/**
|
|
74
|
+
* Observe-mode ghost accounting: what the optimizer WOULD have done.
|
|
75
|
+
* Present only when the API key runs in "observe" mode and a
|
|
76
|
+
* cheaper/blocked route existed.
|
|
77
|
+
*/
|
|
78
|
+
ghost?: {
|
|
79
|
+
route: RouteType | "blocked";
|
|
80
|
+
estimatedSavedUsd: number;
|
|
81
|
+
estimatedSavedMs: number;
|
|
82
|
+
reason: string;
|
|
83
|
+
};
|
|
84
|
+
fallback: string;
|
|
85
|
+
}
|
|
86
|
+
export type RunStatus = "running" | "completed" | "failed" | "blocked";
|
|
87
|
+
export interface Run {
|
|
88
|
+
id: string;
|
|
89
|
+
tenantId: string;
|
|
90
|
+
appId: string;
|
|
91
|
+
agentId?: string;
|
|
92
|
+
/** Pseudonymous subject (end user) identifier. */
|
|
93
|
+
subject?: string;
|
|
94
|
+
status: RunStatus;
|
|
95
|
+
route?: RouteType;
|
|
96
|
+
shadowed?: boolean;
|
|
97
|
+
requestHash: string;
|
|
98
|
+
/** Normalized prompt-shape fingerprint; groups runs into patterns. */
|
|
99
|
+
fingerprint?: string;
|
|
100
|
+
patternId?: string;
|
|
101
|
+
provider?: string;
|
|
102
|
+
model?: string;
|
|
103
|
+
inputTokens: number;
|
|
104
|
+
outputTokens: number;
|
|
105
|
+
costUsd: number;
|
|
106
|
+
/** Estimated USD avoided versus the live path (0 for live runs). */
|
|
107
|
+
savedUsd: number;
|
|
108
|
+
/** Observe mode: estimated USD Punk WOULD have saved (ghost accounting). */
|
|
109
|
+
ghostSavedUsd?: number;
|
|
110
|
+
latencyMs: number;
|
|
111
|
+
startedAt: number;
|
|
112
|
+
completedAt?: number;
|
|
113
|
+
routeExplanation?: RouteExplanation;
|
|
114
|
+
error?: string;
|
|
115
|
+
}
|
|
116
|
+
export type TraceEventType = "request.received" | "policy.checked" | "route.selected" | "model.requested" | "model.failover" | "model.completed" | "chorus.contract" | "chorus.claim_graph" | "chorus.route_selected" | "chorus.verifier" | "chorus.auction" | "chorus.ledger" | "chorus.research_pack" | "chorus.live_synthesis" | "chorus.live_synthesis_empty" | "chorus.live_synthesis_failed" | "chorus.receipt" | "tool.called" | "tool.completed" | "web.fetched" | "som.compiled" | "som.cache_hit" | "som.diffed" | "web.acted" | "side_effect.planned" | "side_effect.executed" | "side_effect.suppressed" | "side_effect.blocked" | "cache.checked" | "cache.hit" | "cache.miss" | "cache.stored" | "artifact.selected" | "artifact.executed" | "artifact.failed" | "artifact.shadowed" | "evaluator.scored" | "pattern.updated" | "artifact.synthesized" | "artifact.state_changed" | "drift.detected" | "tripwire.fired" | "user.feedback" | "run.completed";
|
|
117
|
+
export interface TraceEvent {
|
|
118
|
+
id: string;
|
|
119
|
+
runId: string;
|
|
120
|
+
tenantId: string;
|
|
121
|
+
type: TraceEventType;
|
|
122
|
+
ts: number;
|
|
123
|
+
parentId?: string;
|
|
124
|
+
payload: Record<string, unknown>;
|
|
125
|
+
schemaVersion: 1;
|
|
126
|
+
}
|
|
127
|
+
export type PatternState = "observed" | "candidate" | "watchlisted" | "synthesizing" | "replay_tested" | "shadowing" | "promoted" | "negative" | "retired";
|
|
128
|
+
export type TaskClass = "deterministic" | "schema_deterministic" | "semantic" | "preference" | "open_ended" | "high_risk";
|
|
129
|
+
export interface Pattern {
|
|
130
|
+
id: string;
|
|
131
|
+
tenantId: string;
|
|
132
|
+
appId: string;
|
|
133
|
+
name: string;
|
|
134
|
+
state: PatternState;
|
|
135
|
+
/** Normalized prompt-shape fingerprint (primary cluster key). */
|
|
136
|
+
fingerprint: string;
|
|
137
|
+
toolSequenceFp?: string;
|
|
138
|
+
outputSchemaFp?: string;
|
|
139
|
+
taskClass: TaskClass;
|
|
140
|
+
riskLevel: SideEffectLevel;
|
|
141
|
+
runCount: number;
|
|
142
|
+
totalCostUsd: number;
|
|
143
|
+
avgCostUsd: number;
|
|
144
|
+
avgLatencyMs: number;
|
|
145
|
+
/** How stable inputs→outputs are across observed runs, [0,1]. */
|
|
146
|
+
stabilityScore: number;
|
|
147
|
+
/** expected_value-style prioritization score. */
|
|
148
|
+
optimizableScore: number;
|
|
149
|
+
exampleRunIds: string[];
|
|
150
|
+
negativeReason?: string;
|
|
151
|
+
createdAt: number;
|
|
152
|
+
updatedAt: number;
|
|
153
|
+
}
|
|
154
|
+
export type ArtifactState = "candidate" | "replay_failed" | "replay_passed" | "shadowing" | "shadow_failed" | "approved" | "promoted" | "canary" | "stable" | "degraded" | "quarantined" | "retired";
|
|
155
|
+
export type ArtifactType = "static_response" | "template" | "deterministic_transform" | "ruleset_classifier" | "tool_plan" | "web_extraction" | "hybrid";
|
|
156
|
+
/**
|
|
157
|
+
* Loose representation slot; the gateway's artifact runtime defines and
|
|
158
|
+
* validates the concrete declarative DSL.
|
|
159
|
+
*/
|
|
160
|
+
export type ArtifactRepresentation = {
|
|
161
|
+
dslVersion: 1;
|
|
162
|
+
kind: ArtifactType;
|
|
163
|
+
} & Record<string, unknown>;
|
|
164
|
+
export interface ArtifactProvenance {
|
|
165
|
+
synthesizer: string;
|
|
166
|
+
sourceRunIds: string[];
|
|
167
|
+
holdoutRunIds: string[];
|
|
168
|
+
parentArtifactId?: string;
|
|
169
|
+
notes?: string;
|
|
170
|
+
}
|
|
171
|
+
export interface Artifact {
|
|
172
|
+
id: string;
|
|
173
|
+
tenantId: string;
|
|
174
|
+
patternId: string;
|
|
175
|
+
version: number;
|
|
176
|
+
type: ArtifactType;
|
|
177
|
+
state: ArtifactState;
|
|
178
|
+
representation: ArtifactRepresentation;
|
|
179
|
+
provenance: ArtifactProvenance;
|
|
180
|
+
inputSchema?: Record<string, unknown>;
|
|
181
|
+
outputSchema?: Record<string, unknown>;
|
|
182
|
+
sideEffectLevel: SideEffectLevel;
|
|
183
|
+
/** Successes + prior. Updated on every replay/shadow/live evaluation. */
|
|
184
|
+
alpha: number;
|
|
185
|
+
/** Failures + prior. */
|
|
186
|
+
beta: number;
|
|
187
|
+
/** Lower-bound confidence derived from the posterior; the router gates on this. */
|
|
188
|
+
confidence: number;
|
|
189
|
+
replayPasses: number;
|
|
190
|
+
replayFails: number;
|
|
191
|
+
shadowPasses: number;
|
|
192
|
+
shadowFails: number;
|
|
193
|
+
livePasses: number;
|
|
194
|
+
liveFails: number;
|
|
195
|
+
estCostUsd: number;
|
|
196
|
+
estLatencyMs: number;
|
|
197
|
+
createdAt: number;
|
|
198
|
+
promotedAt?: number;
|
|
199
|
+
lastEvaluatedAt?: number;
|
|
200
|
+
stateReason?: string;
|
|
201
|
+
}
|
|
202
|
+
export interface PromotionGateStatus {
|
|
203
|
+
eligible: boolean;
|
|
204
|
+
autoPromotable: boolean;
|
|
205
|
+
reasons: string[];
|
|
206
|
+
}
|
|
207
|
+
export type EvaluationKind = "replay" | "shadow" | "live";
|
|
208
|
+
export interface ArtifactEvaluation {
|
|
209
|
+
id: string;
|
|
210
|
+
artifactId: string;
|
|
211
|
+
tenantId: string;
|
|
212
|
+
kind: EvaluationKind;
|
|
213
|
+
runId?: string;
|
|
214
|
+
pass: boolean;
|
|
215
|
+
structuralPass: boolean;
|
|
216
|
+
semanticScore: number;
|
|
217
|
+
sideEffectPass: boolean;
|
|
218
|
+
expected?: string;
|
|
219
|
+
actual?: string;
|
|
220
|
+
details?: string;
|
|
221
|
+
createdAt: number;
|
|
222
|
+
}
|
|
223
|
+
/** Mirrors Plasmate's Som struct (som_version "0.1"). */
|
|
224
|
+
export interface SomSnapshot {
|
|
225
|
+
som_version: string;
|
|
226
|
+
url: string;
|
|
227
|
+
title: string;
|
|
228
|
+
lang: string;
|
|
229
|
+
regions: SomRegion[];
|
|
230
|
+
meta: {
|
|
231
|
+
html_bytes: number;
|
|
232
|
+
som_bytes: number;
|
|
233
|
+
element_count: number;
|
|
234
|
+
interactive_count: number;
|
|
235
|
+
};
|
|
236
|
+
}
|
|
237
|
+
export interface SomRegion {
|
|
238
|
+
id: string;
|
|
239
|
+
role: string;
|
|
240
|
+
label?: string;
|
|
241
|
+
action?: string;
|
|
242
|
+
method?: string;
|
|
243
|
+
elements: SomElement[];
|
|
244
|
+
}
|
|
245
|
+
export interface SomElement {
|
|
246
|
+
id: string;
|
|
247
|
+
role: string;
|
|
248
|
+
text?: string;
|
|
249
|
+
label?: string;
|
|
250
|
+
actions?: string[];
|
|
251
|
+
attrs?: Record<string, unknown>;
|
|
252
|
+
children?: SomElement[];
|
|
253
|
+
}
|
|
254
|
+
export interface SomDiffEntry {
|
|
255
|
+
kind: "added" | "removed" | "changed";
|
|
256
|
+
regionId: string;
|
|
257
|
+
elementId?: string;
|
|
258
|
+
field?: string;
|
|
259
|
+
before?: string;
|
|
260
|
+
after?: string;
|
|
261
|
+
/** Semantic weight: pricing/CTA/form changes matter more than footer noise. */
|
|
262
|
+
significance: "high" | "medium" | "low";
|
|
263
|
+
}
|
|
264
|
+
export interface SomDiff {
|
|
265
|
+
url: string;
|
|
266
|
+
beforeFingerprint: string;
|
|
267
|
+
afterFingerprint: string;
|
|
268
|
+
entries: SomDiffEntry[];
|
|
269
|
+
/** Aggregate drift signal in [0,1]. */
|
|
270
|
+
driftScore: number;
|
|
271
|
+
}
|
|
272
|
+
/** Protocol-level actions an agent can take on a SOM page (no JS engine). */
|
|
273
|
+
export type WebActionKind = "click" | "type" | "select" | "submit";
|
|
274
|
+
export interface WebActionIntent {
|
|
275
|
+
action: WebActionKind;
|
|
276
|
+
/** SOM element id (e_…) — or a region id (r_form…) for submit. */
|
|
277
|
+
target: string;
|
|
278
|
+
value?: string;
|
|
279
|
+
}
|
|
280
|
+
export interface WebActionResult {
|
|
281
|
+
ok: boolean;
|
|
282
|
+
action: WebActionKind;
|
|
283
|
+
target: string;
|
|
284
|
+
/** Element/region id the engine resolved the target to. */
|
|
285
|
+
resolved?: string;
|
|
286
|
+
/** True when the action caused a page navigation (link follow / form submit). */
|
|
287
|
+
navigated?: boolean;
|
|
288
|
+
/** Page URL after the action. */
|
|
289
|
+
url: string;
|
|
290
|
+
/** URL the action attempted before redirects, when it caused navigation. */
|
|
291
|
+
requestedUrl?: string;
|
|
292
|
+
error?: string;
|
|
293
|
+
/**
|
|
294
|
+
* For successful form submissions, including submit-button clicks: the
|
|
295
|
+
* serialized field set that was posted (name -> value), so the operator can
|
|
296
|
+
* see exactly what was sent.
|
|
297
|
+
*/
|
|
298
|
+
posted?: Record<string, string>;
|
|
299
|
+
}
|
|
300
|
+
export interface SavingsSummary {
|
|
301
|
+
tenantId: string;
|
|
302
|
+
totalRuns: number;
|
|
303
|
+
liveRuns: number;
|
|
304
|
+
optimizedRuns: number;
|
|
305
|
+
blockedRuns: number;
|
|
306
|
+
totalCostUsd: number;
|
|
307
|
+
totalSavedUsd: number;
|
|
308
|
+
/** Observe-mode ghost accounting: sum of per-run ghostSavedUsd. */
|
|
309
|
+
ghostSavedUsd: number;
|
|
310
|
+
totalSavedMs: number;
|
|
311
|
+
cacheHits: number;
|
|
312
|
+
artifactHits: number;
|
|
313
|
+
cacheHitRate: number;
|
|
314
|
+
artifactHitRate: number;
|
|
315
|
+
somTokensSaved: number;
|
|
316
|
+
}
|
|
317
|
+
export interface McpServerRecord {
|
|
318
|
+
id: string;
|
|
319
|
+
tenantId: string;
|
|
320
|
+
name: string;
|
|
321
|
+
transport: "stdio" | "http";
|
|
322
|
+
command?: string;
|
|
323
|
+
args?: string[];
|
|
324
|
+
url?: string;
|
|
325
|
+
/** Values may be cred:<credentialId> references resolved at connect time. */
|
|
326
|
+
env?: Record<string, string>;
|
|
327
|
+
headers?: Record<string, string>;
|
|
328
|
+
enabled: boolean;
|
|
329
|
+
status: "unknown" | "ok" | "error";
|
|
330
|
+
lastTestedAt?: number;
|
|
331
|
+
lastError?: string;
|
|
332
|
+
toolCount: number;
|
|
333
|
+
createdAt: number;
|
|
334
|
+
updatedAt: number;
|
|
335
|
+
}
|
|
336
|
+
export interface McpTestResult {
|
|
337
|
+
ok: boolean;
|
|
338
|
+
toolCount?: number;
|
|
339
|
+
tools?: Array<{
|
|
340
|
+
name: string;
|
|
341
|
+
description?: string;
|
|
342
|
+
inputSchema?: unknown;
|
|
343
|
+
}>;
|
|
344
|
+
error?: string;
|
|
345
|
+
latencyMs: number;
|
|
346
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@punktechnologies/sdk",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Dependency-free TypeScript SDK for Punk, the adaptive runtime for production AI agents.",
|
|
5
|
+
"license": "Apache-2.0",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"packageManager": "bun@1.3.5",
|
|
8
|
+
"main": "./dist/index.js",
|
|
9
|
+
"types": "./dist/index.d.ts",
|
|
10
|
+
"exports": {
|
|
11
|
+
".": {
|
|
12
|
+
"types": "./dist/index.d.ts",
|
|
13
|
+
"import": "./dist/index.js",
|
|
14
|
+
"default": "./dist/index.js"
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
"files": [
|
|
18
|
+
"dist",
|
|
19
|
+
"README.md",
|
|
20
|
+
"LICENSE"
|
|
21
|
+
],
|
|
22
|
+
"sideEffects": false,
|
|
23
|
+
"engines": {
|
|
24
|
+
"node": ">=18"
|
|
25
|
+
},
|
|
26
|
+
"scripts": {
|
|
27
|
+
"build": "bun build src/index.ts --outdir dist --target node --format esm && tsc -p tsconfig.build.json",
|
|
28
|
+
"test": "bun test",
|
|
29
|
+
"typecheck": "tsc --noEmit",
|
|
30
|
+
"pack:check": "npm pack --dry-run",
|
|
31
|
+
"prepack": "bun run build",
|
|
32
|
+
"prepublishOnly": "bun run build && bun run test && bun run typecheck"
|
|
33
|
+
},
|
|
34
|
+
"publishConfig": {
|
|
35
|
+
"access": "public"
|
|
36
|
+
},
|
|
37
|
+
"repository": {
|
|
38
|
+
"type": "git",
|
|
39
|
+
"url": "git+https://github.com/PunkTechnologies/punk-sdk.git"
|
|
40
|
+
},
|
|
41
|
+
"bugs": {
|
|
42
|
+
"url": "https://github.com/PunkTechnologies/punk-sdk/issues"
|
|
43
|
+
},
|
|
44
|
+
"homepage": "https://punktechnologies.com",
|
|
45
|
+
"keywords": [
|
|
46
|
+
"ai",
|
|
47
|
+
"agents",
|
|
48
|
+
"llm",
|
|
49
|
+
"gateway",
|
|
50
|
+
"openai-compatible",
|
|
51
|
+
"anthropic",
|
|
52
|
+
"caching",
|
|
53
|
+
"tracing",
|
|
54
|
+
"observability",
|
|
55
|
+
"governance",
|
|
56
|
+
"side-effects",
|
|
57
|
+
"punk"
|
|
58
|
+
],
|
|
59
|
+
"devDependencies": {
|
|
60
|
+
"@types/bun": "^1.2.0",
|
|
61
|
+
"@types/node": "^25.9.2",
|
|
62
|
+
"typescript": "^5.7.0"
|
|
63
|
+
}
|
|
64
|
+
}
|