@punktechnologies/sdk 0.1.0 → 0.1.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/LICENSE CHANGED
@@ -9,51 +9,50 @@ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
9
9
  "License" shall mean the terms and conditions for use, reproduction, and
10
10
  distribution as defined by Sections 1 through 9 of this document.
11
11
 
12
- "Licensor" shall mean the copyright owner or entity authorized by the
13
- copyright owner that is granting the License.
12
+ "Licensor" shall mean the copyright owner or entity authorized by the copyright
13
+ owner that is granting the License.
14
14
 
15
- "Legal Entity" shall mean the union of the acting entity and all other
16
- entities that control, are controlled by, or are under common control with
17
- that entity. For the purposes of this definition, "control" means (i) the
18
- power, direct or indirect, to cause the direction or management of such
19
- entity, whether by contract or otherwise, or (ii) ownership of fifty percent
20
- (50%) or more of the outstanding shares, or (iii) beneficial ownership of such
21
- entity.
15
+ "Legal Entity" shall mean the union of the acting entity and all other entities
16
+ that control, are controlled by, or are under common control with that entity.
17
+ For the purposes of this definition, "control" means (i) the power, direct or
18
+ indirect, to cause the direction or management of such entity, whether by
19
+ contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the
20
+ outstanding shares, or (iii) beneficial ownership of such entity.
22
21
 
23
22
  "You" (or "Your") shall mean an individual or Legal Entity exercising
24
23
  permissions granted by this License.
25
24
 
26
- "Source" form shall mean the preferred form for making modifications,
27
- including but not limited to software source code, documentation source, and
28
- configuration files.
25
+ "Source" form shall mean the preferred form for making modifications, including
26
+ but not limited to software source code, documentation source, and configuration
27
+ files.
29
28
 
30
29
  "Object" form shall mean any form resulting from mechanical transformation or
31
- translation of a Source form, including but not limited to compiled object
32
- code, generated documentation, and conversions to other media types.
30
+ translation of a Source form, including but not limited to compiled object code,
31
+ generated documentation, and conversions to other media types.
33
32
 
34
- "Work" shall mean the work of authorship, whether in Source or Object form,
35
- made available under the License, as indicated by a copyright notice that is
36
- included in or attached to the work.
33
+ "Work" shall mean the work of authorship, whether in Source or Object form, made
34
+ available under the License, as indicated by a copyright notice that is included
35
+ in or attached to the work.
37
36
 
38
37
  "Derivative Works" shall mean any work, whether in Source or Object form, that
39
38
  is based on (or derived from) the Work and for which the editorial revisions,
40
39
  annotations, elaborations, or other modifications represent, as a whole, an
41
- original work of authorship. For the purposes of this License, Derivative
42
- Works shall not include works that remain separable from, or merely link (or
43
- bind by name) to the interfaces of, the Work and Derivative Works thereof.
44
-
45
- "Contribution" shall mean any work of authorship, including the original
46
- version of the Work and any modifications or additions to that Work or
47
- Derivative Works thereof, that is intentionally submitted to Licensor for
48
- inclusion in the Work by the copyright owner or by an individual or Legal
49
- Entity authorized to submit on behalf of the copyright owner. For the purposes
50
- of this definition, "submitted" means any form of electronic, verbal, or
51
- written communication sent to the Licensor or its representatives, including
52
- but not limited to communication on electronic mailing lists, source code
53
- control systems, and issue tracking systems that are managed by, or on behalf
54
- of, the Licensor for the purpose of discussing and improving the Work, but
55
- excluding communication that is conspicuously marked or otherwise designated
56
- in writing by the copyright owner as "Not a Contribution."
40
+ original work of authorship. For the purposes of this License, Derivative Works
41
+ shall not include works that remain separable from, or merely link (or bind by
42
+ name) to the interfaces of, the Work and Derivative Works thereof.
43
+
44
+ "Contribution" shall mean any work of authorship, including the original version
45
+ of the Work and any modifications or additions to that Work or Derivative Works
46
+ thereof, that is intentionally submitted to Licensor for inclusion in the Work by
47
+ the copyright owner or by an individual or Legal Entity authorized to submit on
48
+ behalf of the copyright owner. For the purposes of this definition, "submitted"
49
+ means any form of electronic, verbal, or written communication sent to the
50
+ Licensor or its representatives, including but not limited to communication on
51
+ electronic mailing lists, source code control systems, and issue tracking systems
52
+ that are managed by, or on behalf of, the Licensor for the purpose of discussing
53
+ and improving the Work, but excluding communication that is conspicuously marked
54
+ or otherwise designated in writing by the copyright owner as "Not a
55
+ Contribution."
57
56
 
58
57
  "Contributor" shall mean Licensor and any individual or Legal Entity on behalf
59
58
  of whom a Contribution has been received by Licensor and subsequently
@@ -66,54 +65,51 @@ reproduce, prepare Derivative Works of, publicly display, publicly perform,
66
65
  sublicense, and distribute the Work and such Derivative Works in Source or
67
66
  Object form.
68
67
 
69
- 3. Grant of Patent License. Subject to the terms and conditions of this
70
- License, each Contributor hereby grants to You a perpetual, worldwide,
71
- non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this
72
- section) patent license to make, have made, use, offer to sell, sell, import,
73
- and otherwise transfer the Work, where such license applies only to those
74
- patent claims licensable by such Contributor that are necessarily infringed by
75
- their Contribution(s) alone or by combination of their Contribution(s) with the
76
- Work to which such Contribution(s) was submitted. If You institute patent
77
- litigation against any entity (including a cross-claim or counterclaim in a
78
- lawsuit) alleging that the Work or a Contribution incorporated within the Work
79
- constitutes direct or contributory patent infringement, then any patent
80
- licenses granted to You under this License for that Work shall terminate as of
81
- the date such litigation is filed.
68
+ 3. Grant of Patent License. Subject to the terms and conditions of this License,
69
+ each Contributor hereby grants to You a perpetual, worldwide, non-exclusive,
70
+ no-charge, royalty-free, irrevocable patent license to make, have made, use,
71
+ offer to sell, sell, import, and otherwise transfer the Work, where such license
72
+ applies only to those patent claims licensable by such Contributor that are
73
+ necessarily infringed by their Contribution alone or by combination of their
74
+ Contribution with the Work to which such Contribution was submitted. If You
75
+ institute patent litigation against any entity alleging that the Work or a
76
+ Contribution incorporated within the Work constitutes direct or contributory
77
+ patent infringement, then any patent licenses granted to You under this License
78
+ for that Work shall terminate as of the date such litigation is filed.
82
79
 
83
80
  4. Redistribution. You may reproduce and distribute copies of the Work or
84
81
  Derivative Works thereof in any medium, with or without modifications, and in
85
82
  Source or Object form, provided that You meet the following conditions:
86
83
 
87
- (a) You must give any other recipients of the Work or Derivative Works a copy
88
- of this License; and
84
+ (a) You must give any other recipients of the Work or Derivative Works a copy of
85
+ this License; and
89
86
 
90
- (b) You must cause any modified files to carry prominent notices stating that
91
- You changed the files; and
87
+ (b) You must cause any modified files to carry prominent notices stating that You
88
+ changed the files; and
92
89
 
93
90
  (c) You must retain, in the Source form of any Derivative Works that You
94
91
  distribute, all copyright, patent, trademark, and attribution notices from the
95
- Source form of the Work, excluding those notices that do not pertain to any
96
- part of the Derivative Works; and
92
+ Source form of the Work, excluding those notices that do not pertain to any part
93
+ of the Derivative Works; and
97
94
 
98
95
  (d) If the Work includes a "NOTICE" text file as part of its distribution, then
99
96
  any Derivative Works that You distribute must include a readable copy of the
100
97
  attribution notices contained within such NOTICE file, excluding those notices
101
98
  that do not pertain to any part of the Derivative Works, in at least one of the
102
- following places: within a NOTICE text file distributed as part of the
103
- Derivative Works; within the Source form or documentation, if provided along
104
- with the Derivative Works; or within a display generated by the Derivative
105
- Works, if and wherever such third-party notices normally appear. The contents
106
- of the NOTICE file are for informational purposes only and do not modify the
107
- License. You may add Your own attribution notices within Derivative Works that
108
- You distribute, alongside or as an addendum to the NOTICE text from the Work,
109
- provided that such additional attribution notices cannot be construed as
110
- modifying the License.
99
+ following places: within a NOTICE text file distributed as part of the Derivative
100
+ Works; within the Source form or documentation, if provided along with the
101
+ Derivative Works; or, within a display generated by the Derivative Works, if and
102
+ wherever such third-party notices normally appear. The contents of the NOTICE
103
+ file are for informational purposes only and do not modify the License. You may
104
+ add Your own attribution notices within Derivative Works that You distribute,
105
+ alongside or as an addendum to the NOTICE text from the Work, provided that such
106
+ additional attribution notices cannot be construed as modifying the License.
111
107
 
112
108
  You may add Your own copyright statement to Your modifications and may provide
113
109
  additional or different license terms and conditions for use, reproduction, or
114
- distribution of Your modifications, or for any such Derivative Works as a
115
- whole, provided Your use, reproduction, and distribution of the Work otherwise
116
- complies with the conditions stated in this License.
110
+ distribution of Your modifications, or for any such Derivative Works as a whole,
111
+ provided Your use, reproduction, and distribution of the Work otherwise complies
112
+ with the conditions stated in this License.
117
113
 
118
114
  5. Submission of Contributions. Unless You explicitly state otherwise, any
119
115
  Contribution intentionally submitted for inclusion in the Work by You to the
@@ -130,8 +126,8 @@ reproducing the content of the NOTICE file.
130
126
  7. Disclaimer of Warranty. Unless required by applicable law or agreed to in
131
127
  writing, Licensor provides the Work (and each Contributor provides its
132
128
  Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
133
- KIND, either express or implied, including, without limitation, any warranties
134
- or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
129
+ KIND, either express or implied, including, without limitation, any warranties or
130
+ conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
135
131
  PARTICULAR PURPOSE. You are solely responsible for determining the
136
132
  appropriateness of using or redistributing the Work and assume any risks
137
133
  associated with Your exercise of permissions under this License.
@@ -140,23 +136,21 @@ associated with Your exercise of permissions under this License.
140
136
  tort (including negligence), contract, or otherwise, unless required by
141
137
  applicable law (such as deliberate and grossly negligent acts) or agreed to in
142
138
  writing, shall any Contributor be liable to You for damages, including any
143
- direct, indirect, special, incidental, or consequential damages of any
144
- character arising as a result of this License or out of the use or inability to
145
- use the Work (including but not limited to damages for loss of goodwill, work
146
- stoppage, computer failure or malfunction, or any and all other commercial
147
- damages or losses), even if such Contributor has been advised of the
148
- possibility of such damages.
139
+ direct, indirect, special, incidental, or consequential damages of any character
140
+ arising as a result of this License or out of the use or inability to use the
141
+ Work (including but not limited to damages for loss of goodwill, work stoppage,
142
+ computer failure or malfunction, or any and all other commercial damages or
143
+ losses), even if such Contributor has been advised of the possibility of such
144
+ damages.
149
145
 
150
146
  9. Accepting Warranty or Additional Liability. While redistributing the Work or
151
147
  Derivative Works thereof, You may choose to offer, and charge a fee for,
152
- acceptance of support, warranty, indemnity, or other liability obligations
153
- and/or rights consistent with this License. However, in accepting such
154
- obligations, You may act only on Your own behalf and on Your sole
155
- responsibility, not on behalf of any other Contributor, and only if You agree
156
- to indemnify, defend, and hold each Contributor harmless for any liability
157
- incurred by, or claims asserted against, such Contributor by reason of your
158
- accepting any such warranty or additional liability.
148
+ acceptance of support, warranty, indemnity, or other liability obligations and/or
149
+ rights consistent with this License. However, in accepting such obligations, You
150
+ may act only on Your own behalf and on Your sole responsibility, not on behalf of
151
+ any other Contributor, and only if You agree to indemnify, defend, and hold each
152
+ Contributor harmless for any liability incurred by, or claims asserted against,
153
+ such Contributor by reason of your accepting any such warranty or additional
154
+ liability.
159
155
 
160
156
  END OF TERMS AND CONDITIONS
161
-
162
- Copyright 2026 Punk Technologies, Inc.
package/README.md CHANGED
@@ -1,169 +1,291 @@
1
- # Punk SDK
1
+ # @punktechnologies/sdk
2
2
 
3
- Public TypeScript SDK and integration examples for Punk, the adaptive runtime for production AI agents.
3
+ OpenAI-compatible AI gateway SDK for agent tracing, tool caching, governance, observability, and cost optimization.
4
4
 
5
- Punk sits between your agent and model/tool providers. It gives existing agent apps trace IDs, route explanations, caching, governance, feedback, evidence packets, and optimization telemetry without requiring a rewrite.
5
+ Punk is the adaptive runtime for production AI agents. Put the gateway between your agents and model providers, then use this SDK where gateway traffic alone cannot see enough context: tool tracing, side-effect declarations, tool-result caching, semantic web fetches, feedback, receipts, evidence packets, MCP registry helpers, prompt ingest, and learning/artifact APIs.
6
6
 
7
- This repository contains the public client boundary only: SDK source, types, examples, and developer docs. The hosted Punk runtime, optimizer, learning system, replay/shadow infrastructure, governance implementation, dashboard, and deployment code are not part of this repo.
7
+ Links: [SDK docs](https://punktechnologies.com/docs/sdk), [OpenAI gateway guide](https://punktechnologies.com/docs/openai-compatible-ai-gateway), [Vercel AI SDK](https://punktechnologies.com/docs/vercel-ai-sdk), [LangChain](https://punktechnologies.com/docs/langchain), [Anthropic SDK](https://punktechnologies.com/docs/anthropic-sdk), [Claude Code](https://punktechnologies.com/docs/claude-code).
8
+
9
+ The public SDK contains only the client integration surface. Punk's gateway, learning runtime, policies, replay/shadow engine, dashboard, and operators stay in the private runtime repo and are not part of this package.
8
10
 
9
11
  ## Install
10
12
 
11
13
  ```bash
12
- npm install @punktechnologies/sdk
14
+ npm i @punktechnologies/sdk
13
15
  # or
14
16
  bun add @punktechnologies/sdk
15
17
  ```
16
18
 
17
- Set your gateway URL and API key:
19
+ Zero runtime dependencies. Requires Node 18+ or Bun and a running Punk gateway. For local evaluation from the Punk repo:
18
20
 
19
21
  ```bash
20
- export PUNK_BASE_URL=https://api.punktechnologies.com
21
- export PUNK_API_KEY=pk_...
22
+ bun install
23
+ bun run dev # gateway + dashboard + learning loop on http://localhost:4100
22
24
  ```
23
25
 
24
- For local development against a private gateway:
26
+ For hosted trials, use `baseUrl: "https://app.punktechnologies.com"` with a tenant API key from the dashboard.
25
27
 
26
- ```bash
27
- export PUNK_BASE_URL=http://localhost:4100
28
- ```
28
+ ## Choose Your Path
29
29
 
30
- ## One-Line Gateway Integration
30
+ | Path | Best when | Start here |
31
+ | --- | --- | --- |
32
+ | Gateway-only | You already use OpenAI, Anthropic, Vercel AI SDK, LangChain, or another compatible client. | Change `baseURL` and add `X-Punk-*` headers. |
33
+ | SDK client | You want typed helpers for chat, feedback, savings, runs, artifacts, SOM fetches, web sessions, and MCP registry calls. | Use `new Punk(...)`. |
34
+ | Tool tracing | You need Punk to see tool calls, side-effect levels, and read-only tool-cache eligibility. | Wrap tools with `traceTool(...)`. |
35
+ | Evidence reads | You need route explanations, receipts, or security/support evidence packets. | Call `runDetail`, `receipt`, or `evidencePacket`. |
31
36
 
32
- You do not need this SDK for the first integration. Existing OpenAI-compatible clients can route through Punk by changing `baseURL`:
37
+ ## 60-Second Start
38
+
39
+ **1. Point existing OpenAI-style traffic at Punk.**
40
+
41
+ You do not need this SDK for the core gateway value. OpenAI-style and Anthropic-style clients can talk to Punk by changing the gateway URL.
33
42
 
34
43
  ```ts
35
44
  import OpenAI from "openai";
36
45
 
37
- const root = process.env.PUNK_BASE_URL ?? "https://api.punktechnologies.com";
38
-
39
46
  const client = new OpenAI({
40
- baseURL: `${root.replace(/\/$/, "")}/v1`,
41
- apiKey: process.env.PUNK_API_KEY,
42
- defaultHeaders: {
43
- "X-Punk-App": "support-app",
44
- "X-Punk-Agent": "triage-agent",
45
- "X-Punk-Subject": "user-123"
46
- }
47
+ baseURL: "http://localhost:4100/v1",
48
+ apiKey: process.env.PUNK_API_KEY ?? "punk-local",
49
+ defaultHeaders: { "X-Punk-App": "my-app" },
47
50
  });
51
+ ```
48
52
 
49
- const { data, response } = await client.chat.completions
50
- .create({
51
- model: "gpt-4o",
52
- messages: [{ role: "user", content: "Classify this ticket: refund request" }]
53
- })
54
- .withResponse();
53
+ **2. Use the SDK when you need the richer runtime surface.**
55
54
 
56
- console.log(response.headers.get("x-punk-run-id"));
57
- console.log(response.headers.get("x-punk-route"));
58
- console.log(data.choices[0]?.message?.content);
55
+ ```ts
56
+ import { Punk } from "@punktechnologies/sdk";
57
+
58
+ const punk = new Punk({ app: "my-app", agent: "my-bot" });
59
+ const result = await punk.chat({
60
+ model: "gpt-4o",
61
+ messages: [{ role: "user", content: "Classify this ticket: refund request" }],
62
+ });
63
+ console.log(result.content, result.route, result.runId);
64
+ // route is "live" on the first call; repeats become "exact_cache" and,
65
+ // once learned and proven, "artifact".
59
66
  ```
60
67
 
61
- The same pattern works with Anthropic SDK, Vercel AI SDK, LangChain, raw HTTP, and other OpenAI-compatible clients. See [`examples/`](examples/).
68
+ **3. Open the dashboard and inspect the run.**
62
69
 
63
- ## Native SDK
70
+ Open `http://localhost:4100` locally, or `https://app.punktechnologies.com` for hosted trials. Every response carries a run id and route; the run detail explains why Punk chose that path and what it saved.
64
71
 
65
- Use `@punktechnologies/sdk` when you want client helpers for tracing tools, feedback, SOM web fetches, route/evidence reads, learning state, and MCP registry operations.
72
+ ## API tour
66
73
 
67
- ```ts
68
- import { Punk } from "@punktechnologies/sdk";
74
+ Construct once per app/agent identity:
69
75
 
76
+ ```ts
70
77
  const punk = new Punk({
71
- baseUrl: process.env.PUNK_BASE_URL,
72
- apiKey: process.env.PUNK_API_KEY,
73
- app: "support-app",
74
- agent: "triage-agent",
75
- subject: "user-123"
78
+ baseUrl: "http://localhost:4100", // default
79
+ apiKey: process.env.PUNK_API_KEY, // only if the gateway requires bearer auth
80
+ app: "support-triage", // X-Punk-App
81
+ agent: "triage-bot", // X-Punk-Agent
82
+ subject: "user-123", // X-Punk-Subject (pseudonymous end user)
76
83
  });
84
+ ```
77
85
 
78
- const result = await punk.chat({
86
+ ### `chat(params)` OpenAI-style completions through the gateway
87
+
88
+ ```ts
89
+ const r = await punk.chat({
79
90
  model: "gpt-4o",
80
- messages: [{ role: "user", content: "Classify this ticket: refund request" }]
91
+ messages: [{ role: "user", content: "hello" }],
92
+ temperature: 0,
81
93
  });
94
+ r.content; // assistant text
95
+ r.runId; // from the x-punk-run-id response header — use it for tracing/feedback
96
+ r.route; // "live" | "exact_cache" | "artifact" | ... (x-punk-route header)
97
+ r.raw; // the full OpenAI-shaped response body
98
+ ```
99
+
100
+ Every response carries a run id and the route Punk chose. `punk.runDetail(r.runId)` returns the full trace and the `RouteExplanation` — why this route, what was rejected, what it saved.
101
+
102
+ For Punk Chorus, use `model: "punk/chorus"` and add Chorus-specific routing fields to the same body. The SDK helper below uses the OpenAI-style chat wire; direct HTTP callers can use the same model id through supported gateway wires.
103
+
104
+ ```ts
105
+ import { Punk, punkChorusChat } from "@punktechnologies/sdk";
106
+
107
+ const punk = new Punk({ app: "support", agent: "chorus-client" });
108
+
109
+ const r = await punk.chat(punkChorusChat({
110
+ messages: [{ role: "user", content: "Build a claim-graph answer with a receipt." }],
111
+ budget_limit_usd: 0.25,
112
+ latency_mode: "balanced",
113
+ quality_mode: "maximum_quality",
114
+ policy_profile: "regulated-support",
115
+ receipt_mode: "full",
116
+ circuit_mode: "learn",
117
+ shadow_mode: true,
118
+ chorus: { requestId: "req_123", workflowId: "wf_support" },
119
+ }));
82
120
 
83
- console.log(result.content);
84
- console.log(result.route);
85
- console.log(result.runId);
121
+ const receipt = await punk.receipt(r.runId); // GET /api/v1/receipts/:id
122
+ // Current gateways may expose the same receipt-style material as an evidence packet:
123
+ const packet = await punk.evidencePacket(r.runId); // GET /api/v1/runs/:id/evidence-packet
86
124
  ```
87
125
 
88
- ### Trace Tools
126
+ Chorus uses one model id with per-request focus controls:
89
127
 
90
- Declare side-effect levels so Punk can cache safe reads and account for writes:
128
+ | Focus | SDK fields |
129
+ | --- | --- |
130
+ | Fast | `latency_mode: "fast"`, optional `quality_mode: "economy"` |
131
+ | Balanced | `latency_mode: "balanced"`, `quality_mode: "balanced"` |
132
+ | Deep reasoning | `latency_mode: "deep"`, `quality_mode: "frontier_optional"` |
133
+ | Source-backed research | `research_mode: "som"`, `research_max_queries`, `research_max_sources` |
134
+ | Maximum quality | `latency_mode: "maximum_quality"`, `quality_mode: "maximum_quality"`, optional `sota_mix`, `live_panel_models`, and `live_synthesis_model` |
135
+ | Private/local | `local_only: true`, optional `allowed_model_classes` |
136
+ | Shadow evaluation | `shadow_mode: true`, `circuit_mode: "learn"` |
137
+
138
+ Use `receipt_mode: "off"` to suppress receipt material. The gateway also accepts `"none"` as a compatibility alias. Use `live_synthesis_required: true` for benchmark or production gates where falling back to a mock or local path would be misleading.
139
+
140
+ ### `traceTool(def)` — declare tools with side-effect levels
141
+
142
+ Wrap a tool so each invocation is traced into its run, and read-only results flow through the tool-result cache:
91
143
 
92
144
  ```ts
93
145
  const lookupAccount = punk.traceTool({
94
146
  name: "crm.lookupAccount",
95
- sideEffectLevel: 1,
96
- ttlSeconds: 300,
97
- execute: async (args: { accountId: string }) => crm.get(args.accountId)
147
+ sideEffectLevel: 1, // read-only external
148
+ ttlSeconds: 300, // level <= 1 + TTL => tool-result cache participation
149
+ execute: async (args: { accountId: string }) => crm.get(args.accountId),
98
150
  });
99
151
 
100
- const account = await lookupAccount({ accountId: "acct_123" }, { runId: result.runId });
152
+ // Pass the runId from the chat that triggered the tool:
153
+ const account = await lookupAccount({ accountId: "acct_42" }, { runId: r.runId });
101
154
  ```
102
155
 
103
- Side-effect levels:
156
+ Side-effect levels (PRD §17):
104
157
 
105
158
  | Level | Meaning | Example |
106
159
  | --- | --- | --- |
107
- | 0 | Pure computation | parse, format, score |
108
- | 1 | Read-only external | search, CRM read, fetch |
109
- | 2 | Reversible/idempotent write | idempotent upsert |
110
- | 3 | User-visible write | email, Slack, ticket create |
111
- | 4 | High-impact write | payment, deletion, permissions |
160
+ | 0 | Pure computation | parse, format, math |
161
+ | 1 | Read-only external | CRM read, search, fetch |
162
+ | 2 | Reversible/idempotent write | upsert with idempotency key |
163
+ | 3 | User-visible write | email, Slack, ticket creation |
164
+ | 4 | High-impact | payments, deletion, permissions |
112
165
 
113
- Undeclared tools default to level 3. Levels 0-1 with a TTL can participate in tool-result caching. Levels 2-4 emit planned/executed side-effect telemetry around execution.
166
+ Undeclared tools default to **level 3** (conservative). Levels 01 with a TTL are cached per tenant/subject; levels 2 emit `side_effect.planned` before execution so replay and shadow runs can suppress them. Without a `runId`, the tool still executes — just untraced. Cache and trace failures never break the tool call.
114
167
 
115
- ### Read Evidence
168
+ ### `feedback(runId, rating, correction?)` — close the loop
116
169
 
117
170
  ```ts
118
- await punk.feedback(result.runId, 1);
171
+ await punk.feedback(r.runId, 1); // thumbs up
172
+ await punk.feedback(r.runId, -1, "should be: billing"); // correction
173
+ ```
174
+
175
+ Feedback feeds the learner: corrections count against pattern stability and artifact confidence.
119
176
 
120
- const detail = await punk.runDetail(result.runId);
121
- console.log(detail.run.routeExplanation);
177
+ ### `fetchSom(url)` semantic web fetch (token savings)
122
178
 
123
- const savings = await punk.savings();
124
- console.log(savings.totalSavedUsd);
179
+ Compiles a page to a Semantic Object Model instead of handing your model raw HTML:
180
+
181
+ ```ts
182
+ const page = await punk.fetchSom("https://example.com/pricing");
183
+ page.som; // regions/elements with stable ids
184
+ page.context; // compact text ready for a prompt
185
+ page.tokensSavedEstimate; // raw-HTML tokens you didn't pay for
186
+ page.cached; // second fetch of the same URL hits the SOM cache
187
+ page.diff; // semantic diff vs. the previous snapshot, when bypassing cache
125
188
  ```
126
189
 
127
- ### Punk Chorus
190
+ A typical marketing page compresses ~10–50x; the savings show up in `punk.savings().somTokensSaved`. Pass `{ bypassCache: true }` to force a refetch and get a semantic diff (pricing changed ≠ footer changed).
128
191
 
129
- Punk Chorus is selected with `model: "punk/chorus"` on the same gateway wire:
192
+ ### Web sessions & actions `punk.web.*`
193
+
194
+ Observation is half the loop; sessions close it. Open a stateful session, act on SOM element ids, get back a fresh SOM + semantic diff after every action:
130
195
 
131
196
  ```ts
132
- import { Punk, punkChorusChat } from "@punktechnologies/sdk";
197
+ const { sessionId, som, context } = await punk.web.openSession("https://example.com");
133
198
 
134
- const answer = await punk.chat(punkChorusChat({
135
- messages: [{ role: "user", content: "Answer with evidence and a receipt." }],
136
- budget_limit_usd: 0.25,
137
- latency_mode: "balanced",
138
- quality_mode: "maximum_quality",
139
- receipt_mode: "full",
140
- research_mode: "som"
141
- }));
199
+ // click a link by its SOM element id (e_…) — navigates and recompiles
200
+ const link = som.regions.flatMap((r) => r.elements).find((e) => e.role === "link");
201
+ const r1 = await punk.web.act(sessionId, { action: "click", target: link.id });
202
+ r1.result.navigated; // true
203
+ r1.diff; // what changed, semantically weighted
204
+
205
+ // fill and submit a form (target a field for type/select, the r_form region for submit)
206
+ await punk.web.act(sessionId, { action: "type", target: "e_abc123", value: "k@example.com" });
207
+ await punk.web.act(sessionId, { action: "select", target: "e_def456", value: "pro" });
208
+ const submit = await punk.web.act(sessionId, { action: "submit", target: "r_form" });
209
+ submit.result.posted; // serialized fields sent by the form submission
210
+
211
+ await punk.web.closeSession(sessionId); // idle sessions auto-close after 5 minutes
212
+ ```
142
213
 
143
- const receipt = await punk.receipt(answer.runId);
214
+ Actions are protocol-level (link follows, urlencoded form submits — no JS engine) and **policy-governed server-side**:
215
+
216
+ | action | side-effect level | governed action | notes |
217
+ | --- | --- | --- | --- |
218
+ | `type`, `select` | 0 | `read:web` | mutate session-local form state only |
219
+ | form-local `click` | 0 | `read:web` | checkbox/radio/reset mutate session state only |
220
+ | navigation `click` | 1 | `read:web` | link navigation = a read of another page |
221
+ | submit-button `click` | 3 | `write:web` | same governance as submitting the form |
222
+ | `submit` | 3 | `write:web` | a real remote write — deniable/holdable by policy (403) |
223
+
224
+ Observe-mode keys can read (click/type/select) but never perform web writes. Every action is audited, and every navigation destination is SSRF-guarded by the gateway.
225
+
226
+ ### Read APIs
227
+
228
+ ```ts
229
+ await punk.savings(); // SavingsSummary: runs, cost, saved USD/ms, hit rates
230
+ await punk.patterns(); // discovered patterns and their lifecycle state
231
+ await punk.artifacts(); // synthesized artifacts with confidence + evidence counts
232
+ await punk.artifactDetail(id); // artifact + replay/shadow evaluations + source pattern
233
+ await punk.runDetail(id); // run + full trace events + side-effect records
234
+ await punk.receipt(id); // Chorus receipt for a run
235
+ await punk.evidencePacket(id); // support/security evidence packet for a run
236
+ await punk.cacheStats(); // per-tier entries and hits
144
237
  ```
145
238
 
146
- ## Repository Contents
239
+ ### Learning lifecycle
147
240
 
148
- ```text
149
- src/ SDK source and public types
150
- test/ SDK behavior tests
151
- examples/ integration examples for common agent stacks
152
- docs/ SDK reference
241
+ ```ts
242
+ const report = await punk.learningTick(); // force a learning pass (it also runs on a timer)
243
+ const artifact = await punk.promoteArtifact(id); // operator approval after replay+shadow proof
153
244
  ```
154
245
 
155
- ## Development
246
+ Promotion is gated: an artifact needs passing replay evidence against historical traces and shadow agreement against live traffic before `promoteArtifact` succeeds. Rollback/quarantine are available via the API and dashboard.
156
247
 
157
- ```bash
158
- bun install
159
- bun run test
160
- bun run build
161
- bun run typecheck
162
- bun run pack:check
248
+ ### Low-level
249
+
250
+ ```ts
251
+ await punk.trace(runId, "tool.completed", { name: "x", result }); // append a trace event
252
+ await punk.ingestPrompt("claude-code", prompt); // side-load an observed prompt
253
+ await punk.toolCacheCheck("crm.lookupAccount", args); // manual cache check (degrades to miss)
254
+ await punk.toolCacheStore("crm.lookupAccount", args, result, 300); // manual store (failures swallowed)
163
255
  ```
164
256
 
165
- The package is dependency-free at runtime and supports Node.js 18+ and Bun.
257
+ External MCP servers for workflow `tool_call` nodes are available through `punk.mcp.listServers()`, `punk.mcp.createServer(...)`, and `punk.mcp.testServer(id)`.
258
+
259
+ ## Headers reference
260
+
261
+ Request headers (set automatically by the SDK; set them yourself with raw OpenAI clients):
262
+
263
+ | Header | Meaning |
264
+ | --- | --- |
265
+ | `X-Punk-App` | Logical application name (groups runs and patterns) |
266
+ | `X-Punk-Agent` | Agent identity within the app |
267
+ | `X-Punk-Subject` | Pseudonymous end-user id — a cache-key safety dimension |
268
+ | `Authorization: Bearer …` | Only when the gateway sets `PUNK_API_KEY` |
269
+
270
+ Response headers on `/v1/chat/completions`:
271
+
272
+ | Header | Meaning |
273
+ | --- | --- |
274
+ | `x-punk-run-id` | The run this response belongs to — feed it to `trace`/`feedback`/`runDetail` |
275
+ | `x-punk-route` | The route served: `live`, `exact_cache`, `tool_cache`, `artifact`, `blocked`, … |
276
+
277
+ ## Error behavior
278
+
279
+ All methods throw `Error("Punk API <METHOD> <path> failed: <status> <statusText> — <body>")` on non-2xx — except telemetry and caching, which degrade silently: trace appends inside `traceTool` never fail the tool call, `toolCacheCheck` degrades to a miss, `toolCacheStore` is fire-and-forget. The gateway itself fails open: if an optimized route errors, the request falls back to the live provider.
166
280
 
167
- ## Security
281
+ ## More
168
282
 
169
- Security reports go to security@punktechnologies.com. Do not disclose vulnerabilities, secrets, customer data, or governance bypasses in public issues.
283
+ - [Punk in 30 Minutes](https://punktechnologies.com/docs/onboarding)
284
+ - [SDK Reference](https://punktechnologies.com/docs/sdk)
285
+ - [OpenAI-Compatible AI Gateway](https://punktechnologies.com/docs/openai-compatible-ai-gateway)
286
+ - [Vercel AI SDK](https://punktechnologies.com/docs/vercel-ai-sdk)
287
+ - [LangChain](https://punktechnologies.com/docs/langchain)
288
+ - [Anthropic SDK](https://punktechnologies.com/docs/anthropic-sdk)
289
+ - [Claude Code](https://punktechnologies.com/docs/claude-code)
290
+ - [Agent Observability & Tool Caching](https://punktechnologies.com/docs/agent-observability-tool-caching)
291
+ - [examples/](https://github.com/PunkTechnologies/punk/tree/main/examples) — OpenAI SDK, Anthropic SDK, Vercel AI SDK, LangChain, SDK, Claude Code, raw curl
package/SECURITY.md ADDED
@@ -0,0 +1,11 @@
1
+ # Security
2
+
3
+ Please report suspected vulnerabilities privately:
4
+
5
+ ```text
6
+ security@punktechnologies.com
7
+ ```
8
+
9
+ Do not open a public issue for suspected credential exposure, auth bypass, tenant isolation issues, side-effect governance bypasses, replay/shadow suppression failures, SSRF, or package supply-chain compromise.
10
+
11
+ The SDK is dependency-free and published from `packages/sdk` in `PunkTechnologies/punk`. Release provenance is enabled in package metadata.