agentfootprint 9.7.0 → 9.9.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/dist/adapters/identity/vault.js +336 -0
- package/dist/adapters/identity/vault.js.map +1 -0
- package/dist/adapters/observability/audit.js +2 -28
- package/dist/adapters/observability/audit.js.map +1 -1
- package/dist/adapters/observability/file.js +307 -0
- package/dist/adapters/observability/file.js.map +1 -0
- package/dist/adapters/observability/githubBugReporter.js +461 -0
- package/dist/adapters/observability/githubBugReporter.js.map +1 -0
- package/dist/adapters/observability/githubDeviceSignIn.js +263 -0
- package/dist/adapters/observability/githubDeviceSignIn.js.map +1 -0
- package/dist/esm/adapters/identity/vault.d.ts +146 -0
- package/dist/esm/adapters/identity/vault.js +332 -0
- package/dist/esm/adapters/identity/vault.js.map +1 -0
- package/dist/esm/adapters/observability/audit.js +1 -27
- package/dist/esm/adapters/observability/audit.js.map +1 -1
- package/dist/esm/adapters/observability/file.d.ts +145 -0
- package/dist/esm/adapters/observability/file.js +303 -0
- package/dist/esm/adapters/observability/file.js.map +1 -0
- package/dist/esm/adapters/observability/githubBugReporter.d.ts +154 -0
- package/dist/esm/adapters/observability/githubBugReporter.js +457 -0
- package/dist/esm/adapters/observability/githubBugReporter.js.map +1 -0
- package/dist/esm/adapters/observability/githubDeviceSignIn.d.ts +131 -0
- package/dist/esm/adapters/observability/githubDeviceSignIn.js +259 -0
- package/dist/esm/adapters/observability/githubDeviceSignIn.js.map +1 -0
- package/dist/esm/identity.d.ts +1 -0
- package/dist/esm/identity.js +4 -0
- package/dist/esm/identity.js.map +1 -1
- package/dist/esm/lib/bug-report/build.d.ts +103 -0
- package/dist/esm/lib/bug-report/build.js +648 -0
- package/dist/esm/lib/bug-report/build.js.map +1 -0
- package/dist/esm/lib/bug-report/index.d.ts +14 -0
- package/dist/esm/lib/bug-report/index.js +13 -0
- package/dist/esm/lib/bug-report/index.js.map +1 -0
- package/dist/esm/lib/bug-report/transcript.d.ts +61 -0
- package/dist/esm/lib/bug-report/transcript.js +124 -0
- package/dist/esm/lib/bug-report/transcript.js.map +1 -0
- package/dist/esm/lib/bug-report/types.d.ts +206 -0
- package/dist/esm/lib/bug-report/types.js +12 -0
- package/dist/esm/lib/bug-report/types.js.map +1 -0
- package/dist/esm/lib/bug-report/zip.d.ts +71 -0
- package/dist/esm/lib/bug-report/zip.js +202 -0
- package/dist/esm/lib/bug-report/zip.js.map +1 -0
- package/dist/esm/lib/libraryVersion.d.ts +23 -0
- package/dist/esm/lib/libraryVersion.js +46 -0
- package/dist/esm/lib/libraryVersion.js.map +1 -0
- package/dist/esm/lib/trace-toolpack/openRecording.d.ts +17 -0
- package/dist/esm/lib/trace-toolpack/openRecording.js +8 -2
- package/dist/esm/lib/trace-toolpack/openRecording.js.map +1 -1
- package/dist/esm/observability-providers.d.ts +6 -1
- package/dist/esm/observability-providers.js +16 -1
- package/dist/esm/observability-providers.js.map +1 -1
- package/dist/esm/observe.d.ts +1 -0
- package/dist/esm/observe.js +6 -0
- package/dist/esm/observe.js.map +1 -1
- package/dist/identity.js +6 -1
- package/dist/identity.js.map +1 -1
- package/dist/lib/bug-report/build.js +656 -0
- package/dist/lib/bug-report/build.js.map +1 -0
- package/dist/lib/bug-report/index.js +18 -0
- package/dist/lib/bug-report/index.js.map +1 -0
- package/dist/lib/bug-report/transcript.js +128 -0
- package/dist/lib/bug-report/transcript.js.map +1 -0
- package/dist/lib/bug-report/types.js +13 -0
- package/dist/lib/bug-report/types.js.map +1 -0
- package/dist/lib/bug-report/zip.js +207 -0
- package/dist/lib/bug-report/zip.js.map +1 -0
- package/dist/lib/libraryVersion.js +51 -0
- package/dist/lib/libraryVersion.js.map +1 -0
- package/dist/lib/trace-toolpack/openRecording.js +9 -2
- package/dist/lib/trace-toolpack/openRecording.js.map +1 -1
- package/dist/observability-providers.js +20 -2
- package/dist/observability-providers.js.map +1 -1
- package/dist/observe.js +14 -6
- package/dist/observe.js.map +1 -1
- package/dist/types/adapters/identity/vault.d.ts +147 -0
- package/dist/types/adapters/identity/vault.d.ts.map +1 -0
- package/dist/types/adapters/observability/audit.d.ts.map +1 -1
- package/dist/types/adapters/observability/file.d.ts +146 -0
- package/dist/types/adapters/observability/file.d.ts.map +1 -0
- package/dist/types/adapters/observability/githubBugReporter.d.ts +155 -0
- package/dist/types/adapters/observability/githubBugReporter.d.ts.map +1 -0
- package/dist/types/adapters/observability/githubDeviceSignIn.d.ts +132 -0
- package/dist/types/adapters/observability/githubDeviceSignIn.d.ts.map +1 -0
- package/dist/types/identity.d.ts +1 -0
- package/dist/types/identity.d.ts.map +1 -1
- package/dist/types/lib/bug-report/build.d.ts +104 -0
- package/dist/types/lib/bug-report/build.d.ts.map +1 -0
- package/dist/types/lib/bug-report/index.d.ts +15 -0
- package/dist/types/lib/bug-report/index.d.ts.map +1 -0
- package/dist/types/lib/bug-report/transcript.d.ts +62 -0
- package/dist/types/lib/bug-report/transcript.d.ts.map +1 -0
- package/dist/types/lib/bug-report/types.d.ts +207 -0
- package/dist/types/lib/bug-report/types.d.ts.map +1 -0
- package/dist/types/lib/bug-report/zip.d.ts +72 -0
- package/dist/types/lib/bug-report/zip.d.ts.map +1 -0
- package/dist/types/lib/libraryVersion.d.ts +24 -0
- package/dist/types/lib/libraryVersion.d.ts.map +1 -0
- package/dist/types/lib/trace-toolpack/openRecording.d.ts +17 -0
- package/dist/types/lib/trace-toolpack/openRecording.d.ts.map +1 -1
- package/dist/types/observability-providers.d.ts +6 -1
- package/dist/types/observability-providers.d.ts.map +1 -1
- package/dist/types/observe.d.ts +1 -0
- package/dist/types/observe.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/observe.js
CHANGED
|
@@ -47,7 +47,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
47
47
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
48
48
|
};
|
|
49
49
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
50
|
-
exports.ledgerGated = exports.ledgerEntryScorer = exports.ledgerToolGate = exports.contextLedger = exports.formatRouteHop = exports.routeRecorder = exports.toolChoiceRecorder = exports.buildChoiceContext = exports.typedEmit = exports.agentThinkingTrace = exports.toolLineageRecorder = exports.attachStatus = exports.LoggingDomains = exports.attachLogging = exports.resilienceRecorder = exports.skillRecorder = exports.permissionRecorder = exports.embeddingRecorder = exports.memoryRecorder = exports.evalRecorder = exports.contextEvaluatedRecorder = exports.toolsRecorder = exports.costRecorder = exports.LiveAgentTurnTracker = exports.LiveToolTracker = exports.LiveLLMTracker = exports.LiveStateRecorder = exports.liveStateRecorder = exports.attachLocalObservability = exports.traceToStepGraph = exports.redactContent = exports.serializeTrace = exports.summarizeVector = exports.summarizeEmbeddings = exports.recordRun = exports.buildStepGraphFromEvents = exports.buildStepGraph = exports.attachFlowchart = exports.runStepRecorder = exports.RunStepRecorder = exports.buildRunSteps = exports.BoundaryRecorder = exports.boundaryRecorder = exports.agentRecorder = exports.compositionRecorder = exports.streamRecorder = exports.ContextRecorder = void 0;
|
|
50
|
+
exports.ledgerGated = exports.ledgerEntryScorer = exports.ledgerToolGate = exports.contextLedger = exports.formatRouteHop = exports.routeRecorder = exports.toolChoiceRecorder = exports.buildChoiceContext = exports.typedEmit = exports.agentThinkingTrace = exports.toolLineageRecorder = exports.attachStatus = exports.LoggingDomains = exports.attachLogging = exports.resilienceRecorder = exports.skillRecorder = exports.permissionRecorder = exports.embeddingRecorder = exports.memoryRecorder = exports.evalRecorder = exports.contextEvaluatedRecorder = exports.toolsRecorder = exports.costRecorder = exports.LiveAgentTurnTracker = exports.LiveToolTracker = exports.LiveLLMTracker = exports.LiveStateRecorder = exports.liveStateRecorder = exports.attachLocalObservability = exports.traceToStepGraph = exports.redactContent = exports.serializeTrace = exports.summarizeVector = exports.summarizeEmbeddings = exports.exportBugReport = exports.describeBugReport = exports.recordRun = exports.buildStepGraphFromEvents = exports.buildStepGraph = exports.attachFlowchart = exports.runStepRecorder = exports.RunStepRecorder = exports.buildRunSteps = exports.BoundaryRecorder = exports.boundaryRecorder = exports.agentRecorder = exports.compositionRecorder = exports.streamRecorder = exports.ContextRecorder = void 0;
|
|
51
51
|
// Tier 1 — context + stream
|
|
52
52
|
var ContextRecorder_js_1 = require("./recorders/core/ContextRecorder.js");
|
|
53
53
|
Object.defineProperty(exports, "ContextRecorder", { enumerable: true, get: function () { return ContextRecorder_js_1.ContextRecorder; } });
|
|
@@ -75,6 +75,14 @@ Object.defineProperty(exports, "buildStepGraphFromEvents", { enumerable: true, g
|
|
|
75
75
|
// every integration used to assemble by hand, each missing a different piece.
|
|
76
76
|
var recordRun_js_1 = require("./recorders/observability/recordRun.js");
|
|
77
77
|
Object.defineProperty(exports, "recordRun", { enumerable: true, get: function () { return recordRun_js_1.recordRun; } });
|
|
78
|
+
// exportBugReport — a bug report IS the evidence. `describeBugReport` measures
|
|
79
|
+
// the run first (selectable units, sizes, the redacted keys by NAME) so a human
|
|
80
|
+
// can consent to exactly what leaves; `exportBugReport` bundles the units they
|
|
81
|
+
// kept as named files plus a real (stored) zip. `githubBugReporter` — in this
|
|
82
|
+
// same door, from the providers barrel — files that bundle.
|
|
83
|
+
var index_js_1 = require("./lib/bug-report/index.js");
|
|
84
|
+
Object.defineProperty(exports, "describeBugReport", { enumerable: true, get: function () { return index_js_1.describeBugReport; } });
|
|
85
|
+
Object.defineProperty(exports, "exportBugReport", { enumerable: true, get: function () { return index_js_1.exportBugReport; } });
|
|
78
86
|
// What a recording keeps of a vector: `{ dims, norm }`, not the bytes (8.20.0).
|
|
79
87
|
// Applied by BoundaryRecorder and recordRun unless `recordEmbeddings: true`;
|
|
80
88
|
// exported so consumers that render or post-process recordings can apply or
|
|
@@ -159,9 +167,9 @@ Object.defineProperty(exports, "formatRouteHop", { enumerable: true, get: functi
|
|
|
159
167
|
// context-ledger — which context pieces EARNED their tokens? Post-run
|
|
160
168
|
// bookkeeping (offers/uses/outcomes from the commit log) feeding the gating
|
|
161
169
|
// seams. See src/lib/context-ledger/README.md.
|
|
162
|
-
var
|
|
163
|
-
Object.defineProperty(exports, "contextLedger", { enumerable: true, get: function () { return
|
|
164
|
-
Object.defineProperty(exports, "ledgerToolGate", { enumerable: true, get: function () { return
|
|
165
|
-
Object.defineProperty(exports, "ledgerEntryScorer", { enumerable: true, get: function () { return
|
|
166
|
-
Object.defineProperty(exports, "ledgerGated", { enumerable: true, get: function () { return
|
|
170
|
+
var index_js_2 = require("./lib/context-ledger/index.js");
|
|
171
|
+
Object.defineProperty(exports, "contextLedger", { enumerable: true, get: function () { return index_js_2.contextLedger; } });
|
|
172
|
+
Object.defineProperty(exports, "ledgerToolGate", { enumerable: true, get: function () { return index_js_2.ledgerToolGate; } });
|
|
173
|
+
Object.defineProperty(exports, "ledgerEntryScorer", { enumerable: true, get: function () { return index_js_2.ledgerEntryScorer; } });
|
|
174
|
+
Object.defineProperty(exports, "ledgerGated", { enumerable: true, get: function () { return index_js_2.ledgerGated; } });
|
|
167
175
|
//# sourceMappingURL=observe.js.map
|
package/dist/observe.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"observe.js","sourceRoot":"","sources":["../src/observe.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;;;;;;;;;;;;;;;;;AAEH,4BAA4B;AAC5B,0EAAmG;AAA1F,qHAAA,eAAe,OAAA;AACxB,wEAAgG;AAAvF,mHAAA,cAAc,OAAA;AAEvB,+BAA+B;AAC/B,kFAGiD;AAF/C,6HAAA,mBAAmB,OAAA;AAGrB,sEAA6F;AAApF,iHAAA,aAAa,OAAA;AACtB,qFAoBuD;AAnBrD,uHAAA,gBAAgB,OAAA;AAChB,uHAAA,gBAAgB,OAAA;AAmBlB,mFAWsD;AAVpD,mHAAA,aAAa,OAAA;AACb,qHAAA,eAAe,OAAA;AACf,qHAAA,eAAe,OAAA;AASjB,uFAWwD;AAVtD,uHAAA,eAAe,OAAA;AACf,sHAAA,cAAc,OAAA;AACd,gIAAA,wBAAwB,OAAA;AAU1B,yEAAyE;AACzE,6EAA6E;AAC7E,6EAA6E;AAC7E,8EAA8E;AAC9E,uEAKgD;AAJ9C,yGAAA,SAAS,OAAA;AAMX,gFAAgF;AAChF,6EAA6E;AAC7E,4EAA4E;AAC5E,iCAAiC;AACjC,qFAIuD;AAHrD,0HAAA,mBAAmB,OAAA;AACnB,sHAAA,eAAe,OAAA;AAIjB,8EAA8E;AAC9E,gFAAgF;AAChF,iEAAiE;AACjE,+DAQ4C;AAP1C,0GAAA,cAAc,OAAA;AACd,yGAAA,aAAa,OAAA;AACb,4GAAA,gBAAgB,OAAA;AAOlB,mEAAmE;AACnE,4EAA4E;AAC5E,mDAAmD;AACnD,yFAIyD;AAHvD,iIAAA,wBAAwB,OAAA;AAK1B,uFAUwD;AATtD,yHAAA,iBAAiB,OAAA;AACjB,yHAAA,iBAAiB,OAAA;AACjB,sHAAA,cAAc,OAAA;AACd,uHAAA,eAAe,OAAA;AACf,4HAAA,oBAAoB,OAAA;AAOtB,6BAA6B;AAC7B,oEAA0F;AAAjF,+GAAA,YAAY,OAAA;AACrB,sEAA6F;AAApF,iHAAA,aAAa,OAAA;AACtB,4FAGsD;AAFpD,uIAAA,wBAAwB,OAAA;AAG1B,oEAA0F;AAAjF,+GAAA,YAAY,OAAA;AACrB,wEAAgG;AAAvF,mHAAA,cAAc,OAAA;AACvB,8EAG+C;AAF7C,yHAAA,iBAAiB,OAAA;AAGnB,gFAGgD;AAF9C,2HAAA,kBAAkB,OAAA;AAGpB,sEAA6F;AAApF,iHAAA,aAAa,OAAA;AACtB,qEAAqE;AACrE,0EAA0E;AAC1E,wEAAwE;AACxE,oDAAoD;AACpD,gFAGgD;AAF9C,2HAAA,kBAAkB,OAAA;AAGpB,mFAMsD;AALpD,mHAAA,aAAa,OAAA;AACb,oHAAA,cAAc,OAAA;AAKhB,iFAIqD;AAHnD,iHAAA,YAAY,OAAA;AAId,4EAA4E;AAC5E,gFAAgF;AAChF,2FAO0D;AANxD,6HAAA,mBAAmB,OAAA;AAOrB,gFAAgF;AAChF,gFAAgF;AAChF,yGASiE;AAR/D,mIAAA,kBAAkB,OAAA;AAUpB,uDAAuD;AACvD,8DAA0D;AAAjD,yGAAA,SAAS,OAAA;AAElB,kEAAkE;AAClE,uEAAuE;AACvE,0EAA0E;AAC1E,4EAA4E;AAC5E,6EAA6E;AAC7E,yDAAyD;AACzD,6CAA2B;AAC3B,sEAAsE;AACtE,uEAAuE;AACvE,qEAAqE;AACrE,oEAAoE;AACpE,yFASyD;AARvD,2HAAA,kBAAkB,OAAA;AAClB,2HAAA,kBAAkB,OAAA;AASpB,+EASoD;AARlD,iHAAA,aAAa,OAAA;AACb,kHAAA,cAAc,OAAA;AAShB,sEAAsE;AACtE,4EAA4E;AAC5E,+CAA+C;AAC/C,0DAKuC;AAJrC,yGAAA,aAAa,OAAA;AACb,0GAAA,cAAc,OAAA;AACd,6GAAA,iBAAiB,OAAA;AACjB,uGAAA,WAAW,OAAA"}
|
|
1
|
+
{"version":3,"file":"observe.js","sourceRoot":"","sources":["../src/observe.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* vaultCredentials — a {@link CredentialProvider} over a HashiCorp-Vault-compatible
|
|
3
|
+
* KV v2 secret store, spoken as plain HTTP.
|
|
4
|
+
*
|
|
5
|
+
* import { vaultCredentials } from 'agentfootprint/security';
|
|
6
|
+
*
|
|
7
|
+
* const credentials = vaultCredentials({
|
|
8
|
+
* address: 'https://vault.internal:8200', // https, or say `allowHttp` out loud
|
|
9
|
+
* mount: 'secret', // KV v2 mount, default 'secret'
|
|
10
|
+
* paths: { github: 'ci/github' }, // service → path INSIDE the mount
|
|
11
|
+
* }); // token: VAULT_TOKEN, or `token`
|
|
12
|
+
*
|
|
13
|
+
* Zero dependencies and no SDK: one `GET` per resolution through the runtime's
|
|
14
|
+
* own `fetch`. Vault's HTTP API is small, stable and the thing every
|
|
15
|
+
* Vault-compatible store (OpenBao, and the Vault-API modes of several managed
|
|
16
|
+
* stores) implements — so the adapter that speaks HTTP works against more
|
|
17
|
+
* backends than the adapter that imports one vendor's client.
|
|
18
|
+
*
|
|
19
|
+
* ## V1 is deliberately one shape, and says so by name
|
|
20
|
+
*
|
|
21
|
+
* | Axis | V1 | Anything else |
|
|
22
|
+
* |---|---|---|
|
|
23
|
+
* | Auth | a **token** (`token` option, else `VAULT_TOKEN`) | AppRole / Kubernetes / JWT / AWS IAM login are **refused by name**, naming the option that would carry them |
|
|
24
|
+
* | Secret engine | **KV v2** (`<mount>/data/<path>`, the `data.data` envelope) | a KV v1 mount is refused by name once the response shape gives it away |
|
|
25
|
+
* | Leases / renewal | **none** — every `getCredential` re-reads the secret | a lease-aware provider is a different object, and the library's model since 9.7.0 is re-resolve-per-call |
|
|
26
|
+
*
|
|
27
|
+
* That is not modesty, it is the honest edge: an auth method the author cannot
|
|
28
|
+
* exercise against a real cluster would be a guess wearing an adapter's clothes.
|
|
29
|
+
* Each refusal names the option it would arrive on, so "tell us your auth shape"
|
|
30
|
+
* is a field report rather than an issue title.
|
|
31
|
+
*
|
|
32
|
+
* ## Field → credential kind
|
|
33
|
+
*
|
|
34
|
+
* A KV v2 read returns `{ data: { data: { …your fields… }, metadata: {…} } }`.
|
|
35
|
+
* The inner object is mapped to a {@link Credential} by the FIRST rule that
|
|
36
|
+
* matches, so a secret written the ordinary way needs no configuration:
|
|
37
|
+
*
|
|
38
|
+
* | Fields present | Becomes | Header it applies |
|
|
39
|
+
* |---|---|---|
|
|
40
|
+
* | `token` | `bearer(token)` | `authorization: Bearer …` |
|
|
41
|
+
* | `api_key` \| `apiKey` \| `key` | `apiKey(value, header ?? 'x-api-key')` | that header |
|
|
42
|
+
* | `username` + `password` | `basic(username, password)` | `authorization: Basic …` |
|
|
43
|
+
* | `headers` (an object of strings) | `headers(map)` | all of them |
|
|
44
|
+
*
|
|
45
|
+
* A secret matching none of them is refused — naming the PATH and the four
|
|
46
|
+
* shapes, never the secret. `toCredential` is the seam for a shop whose fields
|
|
47
|
+
* are named otherwise; it sees the secret and returns a `Credential`, and
|
|
48
|
+
* returning `undefined` falls back to the table above.
|
|
49
|
+
*
|
|
50
|
+
* ## Secrecy (the 8.6.0 two-clause law, applied here)
|
|
51
|
+
*
|
|
52
|
+
* A thrown message reaches the model as a tool result AND rides
|
|
53
|
+
* `agentfootprint.credential.failed`. So every error this adapter raises names
|
|
54
|
+
* **the service, the path and the HTTP status, and nothing from the response
|
|
55
|
+
* body or the token**. Nothing here logs, and no secret value, no `X-Vault-Token`
|
|
56
|
+
* header and no field name from the payload appears in any message it can throw
|
|
57
|
+
* — pinned by a grep-shaped test over every failure path. The credential it
|
|
58
|
+
* returns hides its own secret fields (non-enumerable) and carries `toHeaders`,
|
|
59
|
+
* so `structuredClone` rejects it and it cannot enter tracked scope by accident.
|
|
60
|
+
*
|
|
61
|
+
* @example Dev → prod is the same two lines
|
|
62
|
+
* ```ts
|
|
63
|
+
* // dev
|
|
64
|
+
* const credentials = staticTokens({ github: 'ghp_dev_xxx' });
|
|
65
|
+
* // prod — the tool code does not change
|
|
66
|
+
* const credentials = vaultCredentials({ address: process.env.VAULT_ADDR! });
|
|
67
|
+
* Agent.create({ provider, model, credentials }).build();
|
|
68
|
+
* ```
|
|
69
|
+
*/
|
|
70
|
+
import type { Credential, CredentialProvider } from '../../identity/types.js';
|
|
71
|
+
/** The base options every form shares. */
|
|
72
|
+
interface VaultCredentialsBase {
|
|
73
|
+
/** Vault's base URL, e.g. `https://vault.internal:8200` — **required**, and
|
|
74
|
+
* **https** unless {@link VaultCredentialsBase.allowHttp} says otherwise. No
|
|
75
|
+
* `VAULT_ADDR` fallback: an agent that silently picks up an address from the
|
|
76
|
+
* environment is an agent that reads a different vault when the environment
|
|
77
|
+
* changes under it. Name it. */
|
|
78
|
+
readonly address: string;
|
|
79
|
+
/** The Vault token. Falls back to `VAULT_TOKEN` (the variable every Vault
|
|
80
|
+
* tool already sets). This is a secret: it is sent as `X-Vault-Token` and
|
|
81
|
+
* appears in no message this adapter can throw. */
|
|
82
|
+
readonly token?: string;
|
|
83
|
+
/** Auth method. **`'token'` is the only one V1 implements.** Anything else is
|
|
84
|
+
* refused at construction, by name, with what it would take — see
|
|
85
|
+
* {@link vaultCredentials}. */
|
|
86
|
+
readonly auth?: 'token';
|
|
87
|
+
/** KV v2 mount point. Default `'secret'` (Vault's own default for the KV v2
|
|
88
|
+
* engine). The read URL is `<address>/v1/<mount>/data/<path>`. */
|
|
89
|
+
readonly mount?: string;
|
|
90
|
+
/** Vault Enterprise / HCP namespace, sent as `X-Vault-Namespace`. Omit for
|
|
91
|
+
* open-source Vault and OpenBao, which have no namespaces. */
|
|
92
|
+
readonly namespace?: string;
|
|
93
|
+
/** Map the secret's fields to a {@link Credential} yourself. Returns
|
|
94
|
+
* `undefined` to fall back to the built-in table (`token` / `api_key` /
|
|
95
|
+
* `username`+`password` / `headers`). The seam for a shop whose field names
|
|
96
|
+
* are its own — and the reason this adapter does not need an option per
|
|
97
|
+
* spelling. **Never log or return the fields from here**; they are the
|
|
98
|
+
* secret. */
|
|
99
|
+
readonly toCredential?: (secret: Readonly<Record<string, unknown>>, service: string) => Credential | undefined;
|
|
100
|
+
/** Header name for the `api_key` shape when the secret does not carry its own
|
|
101
|
+
* `header` field. Default `'x-api-key'`. */
|
|
102
|
+
readonly apiKeyHeader?: string;
|
|
103
|
+
/** Request timeout in ms. Default 5000 — a credential resolution sits in
|
|
104
|
+
* front of a tool call, so a hung vault must fail rather than hang a run. */
|
|
105
|
+
readonly timeoutMs?: number;
|
|
106
|
+
/** Allow a plain-`http://` address. **Refused unless you set this**, because
|
|
107
|
+
* the Vault token travels in a request header: over plaintext HTTP, anyone
|
|
108
|
+
* on the path reads a token that can usually read every secret it can reach.
|
|
109
|
+
* Set it only for a loopback dev server (`http://127.0.0.1:8200`). */
|
|
110
|
+
readonly allowHttp?: boolean;
|
|
111
|
+
/** Stable provider id (default `'vault'`). Shows up in "which provider vended
|
|
112
|
+
* this". */
|
|
113
|
+
readonly id?: string;
|
|
114
|
+
/** Test seam — inject `fetch`. Bypasses the network entirely. */
|
|
115
|
+
readonly _fetch?: typeof fetch;
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* How a `service` becomes a path inside the mount. Three arms, and they
|
|
119
|
+
* EXCLUDE each other — two spellings of one rule can disagree, so the type
|
|
120
|
+
* refuses the pair and so does the constructor.
|
|
121
|
+
*/
|
|
122
|
+
type VaultPathMapping = {
|
|
123
|
+
/** `service → path inside the mount`, the {@link staticTokens} shape one
|
|
124
|
+
* level up: the same literal map, holding a path instead of a token. An
|
|
125
|
+
* unknown service is refused by name, listing the known ones. */
|
|
126
|
+
readonly paths: Readonly<Record<string, string>>;
|
|
127
|
+
readonly resolve?: never;
|
|
128
|
+
} | {
|
|
129
|
+
/** `service → path`, computed. Return `undefined` to refuse a service.
|
|
130
|
+
* For the convention-driven shop: ``(s) => `agents/${s}` ``. */
|
|
131
|
+
readonly resolve: (service: string) => string | undefined;
|
|
132
|
+
readonly paths?: never;
|
|
133
|
+
} | {
|
|
134
|
+
/** Neither: the **service id IS the path** under the mount, so
|
|
135
|
+
* `service: 'github'` reads `<mount>/data/github`. */
|
|
136
|
+
readonly paths?: undefined;
|
|
137
|
+
readonly resolve?: undefined;
|
|
138
|
+
};
|
|
139
|
+
export type VaultCredentialsOptions = VaultCredentialsBase & VaultPathMapping;
|
|
140
|
+
/**
|
|
141
|
+
* Build a {@link CredentialProvider} that reads KV v2 secrets from a
|
|
142
|
+
* Vault-compatible store. See {@link VaultCredentialsOptions} for the
|
|
143
|
+
* per-option contract and this module's docstring for the V1 boundary.
|
|
144
|
+
*/
|
|
145
|
+
export declare function vaultCredentials(options: VaultCredentialsOptions): CredentialProvider;
|
|
146
|
+
export {};
|
|
147
|
+
//# sourceMappingURL=vault.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vault.d.ts","sourceRoot":"","sources":["../../../../src/adapters/identity/vault.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoEG;AAEH,OAAO,KAAK,EACV,UAAU,EACV,kBAAkB,EAGnB,MAAM,yBAAyB,CAAC;AAKjC,0CAA0C;AAC1C,UAAU,oBAAoB;IAC5B;;;;qCAIiC;IACjC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB;;wDAEoD;IACpD,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB;;oCAEgC;IAChC,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC;IACxB;uEACmE;IACnE,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB;mEAC+D;IAC/D,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B;;;;;kBAKc;IACd,QAAQ,CAAC,YAAY,CAAC,EAAE,CACtB,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EACzC,OAAO,EAAE,MAAM,KACZ,UAAU,GAAG,SAAS,CAAC;IAC5B;iDAC6C;IAC7C,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B;kFAC8E;IAC9E,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B;;;2EAGuE;IACvE,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC;IAC7B;iBACa;IACb,QAAQ,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC;IACrB,iEAAiE;IACjE,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,KAAK,CAAC;CAChC;AAED;;;;GAIG;AACH,KAAK,gBAAgB,GACjB;IACE;;sEAEkE;IAClE,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACjD,QAAQ,CAAC,OAAO,CAAC,EAAE,KAAK,CAAC;CAC1B,GACD;IACE;qEACiE;IACjE,QAAQ,CAAC,OAAO,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAC;IAC1D,QAAQ,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC;CACxB,GACD;IACE;2DACuD;IACvD,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,CAAC;IAC3B,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,CAAC;CAC9B,CAAC;AAEN,MAAM,MAAM,uBAAuB,GAAG,oBAAoB,GAAG,gBAAgB,CAAC;AAmB9E;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,uBAAuB,GAAG,kBAAkB,CAoIrF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"audit.d.ts","sourceRoot":"","sources":["../../../../src/adapters/observability/audit.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkIG;AAGH,OAAO,EAAiB,sBAAsB,EAAE,MAAM,4BAA4B,CAAC;
|
|
1
|
+
{"version":3,"file":"audit.d.ts","sourceRoot":"","sources":["../../../../src/adapters/observability/audit.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* fileObservability — the typed event stream, one JSON line per event, in a
|
|
3
|
+
* local file.
|
|
4
|
+
*
|
|
5
|
+
* The sink for the shop that has no collector. Every other adapter in this
|
|
6
|
+
* folder ships somewhere: CloudWatch, X-Ray, an OTLP endpoint. A great many
|
|
7
|
+
* on-premises deployments have none of those — they have a directory, a log
|
|
8
|
+
* shipper (Filebeat, Fluent Bit, Vector, `promtail`, `journald`, or a person
|
|
9
|
+
* with `grep`), and a rule that nothing leaves the network. NDJSON on disk is
|
|
10
|
+
* the format all of those already read, so the sink is the file.
|
|
11
|
+
*
|
|
12
|
+
* Zero dependencies: `node:fs`, lazily required at construction so merely
|
|
13
|
+
* importing `agentfootprint/observe` stays browser-safe (this factory is
|
|
14
|
+
* Node-only; calling it in a browser throws by name).
|
|
15
|
+
*
|
|
16
|
+
* ## The line
|
|
17
|
+
*
|
|
18
|
+
* One `JSON.stringify(event)` per line, newline-terminated, appended in
|
|
19
|
+
* dispatch order — the SAME envelope `cloudwatchObservability` puts in a log
|
|
20
|
+
* event, so a query written against one reads the other:
|
|
21
|
+
*
|
|
22
|
+
* ```jsonl
|
|
23
|
+
* {"type":"agentfootprint.agent.turn_start","payload":{…},"meta":{"runId":"…","sessionId":"…"}}
|
|
24
|
+
* {"type":"agentfootprint.stream.tool_end","payload":{…},"meta":{…}}
|
|
25
|
+
* ```
|
|
26
|
+
*
|
|
27
|
+
* Nothing is summarized, bounded or redacted on the way out. **A payload that
|
|
28
|
+
* must not be on that disk must not reach this strategy** — narrow it with
|
|
29
|
+
* `eventTypes` / `tier` / `sampleRate`, or apply a footprintjs
|
|
30
|
+
* `RedactionPolicy` upstream, exactly as with every other sink. (For a bounded
|
|
31
|
+
* record by construction, `auditExport({ payloadMode: 'bounded' })` is the
|
|
32
|
+
* adapter that does that job.)
|
|
33
|
+
*
|
|
34
|
+
* ## Buffered, not synchronous
|
|
35
|
+
*
|
|
36
|
+
* `exportEvent` is sync and never touches the disk: it serializes, buffers, and
|
|
37
|
+
* returns. Batches are appended asynchronously on a size trigger
|
|
38
|
+
* (`maxBufferEvents` / `maxBufferBytes`), on a timer (`flushIntervalMs`), and on
|
|
39
|
+
* `flush()`. A hard kill therefore loses at most the buffer — the price of not
|
|
40
|
+
* making telemetry a term in agent-loop latency. Call `flush()` (or
|
|
41
|
+
* `agent.shutdown()`, which does) at process end; see the 8.12.0 lifecycle laws
|
|
42
|
+
* on {@link BaseStrategy.flush}.
|
|
43
|
+
*
|
|
44
|
+
* ## Rotation is ONE generation, and that is deliberate
|
|
45
|
+
*
|
|
46
|
+
* With `maxBytes` set, a batch that would push the file past the ceiling first
|
|
47
|
+
* renames it to `<path>.1` — **replacing any previous `.1`** — and starts a
|
|
48
|
+
* fresh file. That is the whole policy. There is no `.2`, no compression, no
|
|
49
|
+
* time-based schedule, no cross-process coordination (two processes writing one
|
|
50
|
+
* file each keep their own byte count and will both rotate it). It exists so an
|
|
51
|
+
* unattended agent cannot fill a disk, and for nothing else: **retention is a
|
|
52
|
+
* log-management daemon's job**, and `logrotate` with `copytruncate`, Fluent Bit,
|
|
53
|
+
* or a systemd timer will do it properly. Omit `maxBytes` — the default — and
|
|
54
|
+
* this adapter never renames anything, which is the right choice when a real
|
|
55
|
+
* rotator already owns the file.
|
|
56
|
+
*
|
|
57
|
+
* @example
|
|
58
|
+
* ```ts
|
|
59
|
+
* import { fileObservability } from 'agentfootprint/observe';
|
|
60
|
+
*
|
|
61
|
+
* const telemetry = agent.enable.observability({
|
|
62
|
+
* strategy: fileObservability({
|
|
63
|
+
* path: '/var/log/agentfootprint/events.ndjson',
|
|
64
|
+
* maxBytes: 64 * 1024 * 1024, // safety ceiling; logrotate owns retention
|
|
65
|
+
* }),
|
|
66
|
+
* });
|
|
67
|
+
*
|
|
68
|
+
* // … run …
|
|
69
|
+
* await agent.shutdown(); // flushes + stops everything enabled
|
|
70
|
+
* ```
|
|
71
|
+
*/
|
|
72
|
+
import type { AgentfootprintEvent, AgentfootprintEventType } from '../../events/registry.js';
|
|
73
|
+
import type { ObservabilityStrategy } from '../../strategies/types.js';
|
|
74
|
+
export interface FileObservabilityOptions {
|
|
75
|
+
/** Absolute or relative path to the NDJSON file. **Required.** Its parent
|
|
76
|
+
* directories are created (`recursive`) and the file itself is claimed at
|
|
77
|
+
* construction, so an unwritable path fails where you wrote it rather than
|
|
78
|
+
* at the first event — the only moment a caller is still watching. */
|
|
79
|
+
readonly path: string;
|
|
80
|
+
/** Rotation ceiling in bytes. Omitted → **never rotates** (the right choice
|
|
81
|
+
* when `logrotate` or a shipper already owns the file). Set → a batch that
|
|
82
|
+
* would cross the ceiling first renames the file to `<path>.1`, replacing
|
|
83
|
+
* any previous `.1`, and starts fresh. ONE generation, no compression, no
|
|
84
|
+
* cross-process coordination — see the note in this module's docstring. */
|
|
85
|
+
readonly maxBytes?: number;
|
|
86
|
+
/** Max events buffered before a forced append. Default 100. */
|
|
87
|
+
readonly maxBufferEvents?: number;
|
|
88
|
+
/** Max buffered payload bytes (UTF-8) before a forced append. Default 65536
|
|
89
|
+
* (64 KB) — a local write is cheap, so this is far larger than the network
|
|
90
|
+
* adapters' 10 KB. */
|
|
91
|
+
readonly maxBufferBytes?: number;
|
|
92
|
+
/** Forced-append interval when traffic is sparse, in ms. Default 1000.
|
|
93
|
+
* `0` disables the timer — only size triggers and `flush()` write. */
|
|
94
|
+
readonly flushIntervalMs?: number;
|
|
95
|
+
/** Narrow what lands on the disk. Becomes the strategy's
|
|
96
|
+
* {@link ObservabilityStrategy.relevantEventTypes}, so the dispatcher does
|
|
97
|
+
* not even forward the rest — the filter costs nothing at the hot path.
|
|
98
|
+
* Omitted → every event the `tier` lets through is written. */
|
|
99
|
+
readonly eventTypes?: readonly AgentfootprintEventType[];
|
|
100
|
+
/**
|
|
101
|
+
* Where delivery failures go — a full disk, a revoked permission, a path
|
|
102
|
+
* whose directory was removed under a long-running process.
|
|
103
|
+
*
|
|
104
|
+
* Same law as the network adapters (8.11.0): **telemetry that fails
|
|
105
|
+
* invisibly is indistinguishable from telemetry that works.** Unhandled,
|
|
106
|
+
* failures reach a rate-limited `console.error`. The batch that failed is
|
|
107
|
+
* dropped, never requeued, so a disk that has been full for an hour cannot
|
|
108
|
+
* grow the buffer without bound.
|
|
109
|
+
*/
|
|
110
|
+
readonly onError?: (error: Error, event?: AgentfootprintEvent) => void;
|
|
111
|
+
/** Test seam — inject a filesystem. Bypasses `node:fs` entirely, which is
|
|
112
|
+
* also what lets the rotation policy be asserted without a real disk. */
|
|
113
|
+
readonly _fs?: FileSinkFs;
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* The slice of the filesystem this adapter touches — five calls, named by what
|
|
117
|
+
* the adapter uses them FOR rather than by their `node:fs` signatures.
|
|
118
|
+
*
|
|
119
|
+
* Sync members run once, at construction; the append path is async so the agent
|
|
120
|
+
* loop never waits on a disk.
|
|
121
|
+
*/
|
|
122
|
+
export interface FileSinkFs {
|
|
123
|
+
/** Create the log file's parent directory chain. */
|
|
124
|
+
mkdirSync(dir: string, options: {
|
|
125
|
+
readonly recursive: boolean;
|
|
126
|
+
}): void;
|
|
127
|
+
/** Claim the file at construction. This is the writability refusal: an
|
|
128
|
+
* unwritable path throws HERE, with the caller still on the stack. */
|
|
129
|
+
appendFileSync(file: string, data: string): void;
|
|
130
|
+
/** Current size, so the rotation counter starts from what is already there
|
|
131
|
+
* rather than from zero on every restart. */
|
|
132
|
+
statSync(file: string): {
|
|
133
|
+
readonly size: number;
|
|
134
|
+
};
|
|
135
|
+
/** Append one batch of NDJSON lines. */
|
|
136
|
+
appendFile(file: string, data: string): Promise<void>;
|
|
137
|
+
/** Rotate: `<path>` → `<path>.1`, replacing any previous `.1`. */
|
|
138
|
+
rename(from: string, to: string): Promise<void>;
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* NDJSON-to-a-local-file observability strategy. See
|
|
142
|
+
* {@link FileObservabilityOptions} for the per-option contract, and this
|
|
143
|
+
* module's docstring for the rotation policy and what is NOT bounded.
|
|
144
|
+
*/
|
|
145
|
+
export declare function fileObservability(opts: FileObservabilityOptions): ObservabilityStrategy;
|
|
146
|
+
//# sourceMappingURL=file.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file.d.ts","sourceRoot":"","sources":["../../../../src/adapters/observability/file.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsEG;AAEH,OAAO,KAAK,EAAE,mBAAmB,EAAE,uBAAuB,EAAE,MAAM,0BAA0B,CAAC;AAE7F,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAMvE,MAAM,WAAW,wBAAwB;IACvC;;;2EAGuE;IACvE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB;;;;gFAI4E;IAC5E,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,+DAA+D;IAC/D,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC;IAClC;;2BAEuB;IACvB,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC;2EACuE;IACvE,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC;IAClC;;;oEAGgE;IAChE,QAAQ,CAAC,UAAU,CAAC,EAAE,SAAS,uBAAuB,EAAE,CAAC;IACzD;;;;;;;;;OASG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,EAAE,mBAAmB,KAAK,IAAI,CAAC;IACvE;8EAC0E;IAC1E,QAAQ,CAAC,GAAG,CAAC,EAAE,UAAU,CAAC;CAC3B;AAED;;;;;;GAMG;AACH,MAAM,WAAW,UAAU;IACzB,oDAAoD;IACpD,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE;QAAE,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAA;KAAE,GAAG,IAAI,CAAC;IACvE;2EACuE;IACvE,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACjD;kDAC8C;IAC9C,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG;QAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IAClD,wCAAwC;IACxC,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACtD,kEAAkE;IAClE,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACjD;AAID;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,wBAAwB,GAAG,qBAAqB,CA2LvF"}
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* githubBugReporter — file a bug report, with the run attached, into GitHub.
|
|
3
|
+
*
|
|
4
|
+
* import { exportBugReport, githubBugReporter } from 'agentfootprint/observe';
|
|
5
|
+
*
|
|
6
|
+
* const reporter = githubBugReporter({
|
|
7
|
+
* issueRepo: 'acme/checkout-agent', // where the ISSUE goes
|
|
8
|
+
* evidenceRepo: 'acme/agent-evidence', // where the ZIP goes (default: issueRepo)
|
|
9
|
+
* }); // token: GITHUB_TOKEN, or `token`
|
|
10
|
+
*
|
|
11
|
+
* const { issueUrl, zipUrl } = await reporter.file(report);
|
|
12
|
+
*
|
|
13
|
+
* Two HTTP calls and no SDK: `PUT /repos/{evidenceRepo}/contents/{path}` commits
|
|
14
|
+
* the zip, `POST /repos/{issueRepo}/issues` files the issue with a manifest
|
|
15
|
+
* table and a link to the committed bundle. Plain `fetch`, zero dependencies,
|
|
16
|
+
* `apiBase` for GitHub Enterprise Server — so this works unchanged on a network
|
|
17
|
+
* that never reaches github.com.
|
|
18
|
+
*
|
|
19
|
+
* ## TWIN TARGETS: the issue and the evidence may live in different repos
|
|
20
|
+
*
|
|
21
|
+
* The case this exists for: a field tester finds a bug in a LIBRARY. The issue
|
|
22
|
+
* belongs in the library's public repo, where the maintainers and the next
|
|
23
|
+
* person to hit it will find it. The evidence — a real run, with real prompts,
|
|
24
|
+
* real tool arguments and real retrieved documents — does not. So the zip goes
|
|
25
|
+
* into a PRIVATE repo the maintainers can read, and the issue links it and says
|
|
26
|
+
* plainly that the evidence is private.
|
|
27
|
+
*
|
|
28
|
+
* ```ts
|
|
29
|
+
* githubBugReporter({
|
|
30
|
+
* issueRepo: 'footprintjs/agentfootprint', // public — the conversation
|
|
31
|
+
* evidenceRepo: 'acme/af-bug-evidence', // private — the run
|
|
32
|
+
* });
|
|
33
|
+
* ```
|
|
34
|
+
*
|
|
35
|
+
* ## DEFAULT-TARGET DOCTRINE
|
|
36
|
+
*
|
|
37
|
+
* **File into the application's OWN repo.** That is the default (`evidenceRepo`
|
|
38
|
+
* defaults to `issueRepo`) and it is the right default: the run belongs to the
|
|
39
|
+
* organisation that produced it. Sending a run's evidence across an
|
|
40
|
+
* organisational boundary — to a vendor, to an upstream library, to anyone
|
|
41
|
+
* whose access your company did not grant — is a HUMAN act with consequences a
|
|
42
|
+
* library cannot weigh. This adapter will do it, because a field tester filing
|
|
43
|
+
* upstream is a real and valuable thing; it will not do it quietly. The
|
|
44
|
+
* consent manifest (`describeBugReport`) exists so a person sees exactly what
|
|
45
|
+
* would leave before it does, and this reporter refuses to commit evidence to a
|
|
46
|
+
* PUBLIC repo unless the caller says `acknowledgePublicEvidence: true` out loud.
|
|
47
|
+
*
|
|
48
|
+
* ## Provisioning the token: fine-grained, and scoped to two repos
|
|
49
|
+
*
|
|
50
|
+
* Use a **fine-grained personal access token** (GitHub → Settings → Developer
|
|
51
|
+
* settings → Fine-grained tokens), scoped to ONLY `issueRepo` and
|
|
52
|
+
* `evidenceRepo`, with exactly two permissions — **Contents: read and write**
|
|
53
|
+
* (to commit the zip) and **Issues: read and write** (to file the issue) — and
|
|
54
|
+
* an expiry date. Put it in the server's environment as `GITHUB_TOKEN`, or pass
|
|
55
|
+
* it as `token`.
|
|
56
|
+
*
|
|
57
|
+
* The contrast matters: a CLASSIC PAT's `repo` scope is coarse — it grants
|
|
58
|
+
* read/write across every repository the account can reach, so a leaked
|
|
59
|
+
* bug-report token is a leaked key to the whole account. With a fine-grained
|
|
60
|
+
* token scoped as above, the blast radius of a leak is filing bug reports and
|
|
61
|
+
* committing files to one evidence repo, and nothing else. GitHub App
|
|
62
|
+
* installation tokens (short-lived, org-installed, revocable centrally) are the
|
|
63
|
+
* next rung for an organisation that wants one; this adapter does not mint
|
|
64
|
+
* them — hand it the token your app already obtained.
|
|
65
|
+
*
|
|
66
|
+
* ## Secrecy (the two-clause law)
|
|
67
|
+
*
|
|
68
|
+
* The token appears in no message, no error and no log this adapter can
|
|
69
|
+
* produce, and neither does the bundle's content. A failed request is reported
|
|
70
|
+
* as **the status and GitHub's own `message` field** — never the request, never
|
|
71
|
+
* the headers, never the body that carried the token, never a byte of
|
|
72
|
+
* evidence. Transport failures are re-wrapped rather than rethrown, because a
|
|
73
|
+
* `fetch` implementation is free to put the request (headers included) into the
|
|
74
|
+
* error it throws. Nothing here writes to a console. Pinned by a suite that
|
|
75
|
+
* forces every failure path and greps the message, the stack and the JSON
|
|
76
|
+
* projection for the token.
|
|
77
|
+
*
|
|
78
|
+
* @example A server route (the app's own repo, the default target)
|
|
79
|
+
* ```ts
|
|
80
|
+
* const reporter = githubBugReporter({ issueRepo: 'acme/checkout-agent' });
|
|
81
|
+
* app.post('/bug-report', async (req, res) => {
|
|
82
|
+
* const report = exportBugReport(recordings.get(req.body.runId), req.body.fields);
|
|
83
|
+
* res.json(await reporter.file(report));
|
|
84
|
+
* });
|
|
85
|
+
* ```
|
|
86
|
+
*/
|
|
87
|
+
import type { BugReport } from '../../lib/bug-report/index.js';
|
|
88
|
+
export interface GithubBugReporterOptions {
|
|
89
|
+
/** `owner/name` of the repo the ISSUE is filed in. Required. */
|
|
90
|
+
readonly issueRepo: string;
|
|
91
|
+
/**
|
|
92
|
+
* `owner/name` of the repo the evidence ZIP is committed to. Defaults to
|
|
93
|
+
* {@link issueRepo}. Point it at a PRIVATE repo when the issue itself is
|
|
94
|
+
* public — see the twin-target section above.
|
|
95
|
+
*/
|
|
96
|
+
readonly evidenceRepo?: string;
|
|
97
|
+
/**
|
|
98
|
+
* The GitHub token. Falls back to the `GITHUB_TOKEN` environment variable.
|
|
99
|
+
* It needs **Contents: read/write on `evidenceRepo`** and **Issues:
|
|
100
|
+
* read/write on `issueRepo`**; filing an issue on a public repo needs only a
|
|
101
|
+
* valid account token. This is a secret: it is sent as an `Authorization`
|
|
102
|
+
* header and appears in no message this adapter can throw.
|
|
103
|
+
*/
|
|
104
|
+
readonly token?: string;
|
|
105
|
+
/** Directory inside `evidenceRepo` for the bundles. Default `'bug-reports'`. */
|
|
106
|
+
readonly dir?: string;
|
|
107
|
+
/** Labels applied to the issue. Default: none. */
|
|
108
|
+
readonly labels?: readonly string[];
|
|
109
|
+
/** Branch to commit the evidence to. Default: the repo's default branch. */
|
|
110
|
+
readonly branch?: string;
|
|
111
|
+
/** API root. Default `https://api.github.com`; for GitHub Enterprise Server
|
|
112
|
+
* it is `https://github.your-company.com/api/v3`. */
|
|
113
|
+
readonly apiBase?: string;
|
|
114
|
+
/**
|
|
115
|
+
* Commit evidence to a PUBLIC repo deliberately.
|
|
116
|
+
*
|
|
117
|
+
* Off by default: a bundle carries a real run — prompts, tool arguments,
|
|
118
|
+
* retrieved documents — and a public repo publishes it to the internet
|
|
119
|
+
* permanently. Set this only when the evidence is synthetic, or when a human
|
|
120
|
+
* has read the manifest and decided.
|
|
121
|
+
*/
|
|
122
|
+
readonly acknowledgePublicEvidence?: boolean;
|
|
123
|
+
/** Refuse a zip larger than this before uploading. Default 24 MB. */
|
|
124
|
+
readonly maxZipBytes?: number;
|
|
125
|
+
/** Test seam — inject `fetch`. Bypasses the network entirely. */
|
|
126
|
+
readonly _fetch?: typeof fetch;
|
|
127
|
+
}
|
|
128
|
+
/** What a filed report leaves behind. */
|
|
129
|
+
export interface FiledBugReport {
|
|
130
|
+
/** The issue, on `issueRepo`. */
|
|
131
|
+
readonly issueUrl: string;
|
|
132
|
+
/** The committed bundle's blob page, on `evidenceRepo`. */
|
|
133
|
+
readonly zipUrl: string;
|
|
134
|
+
/** Path inside `evidenceRepo`. */
|
|
135
|
+
readonly zipPath: string;
|
|
136
|
+
/** `owner/name` the evidence went to. */
|
|
137
|
+
readonly evidenceRepo: string;
|
|
138
|
+
/**
|
|
139
|
+
* Whether the evidence repo's visibility was actually READ before committing.
|
|
140
|
+
*
|
|
141
|
+
* `false` means the metadata call failed — usually a token that can write
|
|
142
|
+
* contents but not read repository metadata. The commit proceeds (a
|
|
143
|
+
* permissions quirk must not block a bug report) and this field says the
|
|
144
|
+
* guard did not run, so nobody mistakes an unchecked upload for a checked one.
|
|
145
|
+
*/
|
|
146
|
+
readonly checkedVisibility: boolean;
|
|
147
|
+
/** The answer, when the check ran. */
|
|
148
|
+
readonly evidenceRepoPrivate?: boolean;
|
|
149
|
+
}
|
|
150
|
+
/** Files a finished {@link BugReport}. */
|
|
151
|
+
export interface BugReporter {
|
|
152
|
+
file(report: BugReport): Promise<FiledBugReport>;
|
|
153
|
+
}
|
|
154
|
+
export declare function githubBugReporter(options: GithubBugReporterOptions): BugReporter;
|
|
155
|
+
//# sourceMappingURL=githubBugReporter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"githubBugReporter.d.ts","sourceRoot":"","sources":["../../../../src/adapters/observability/githubBugReporter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqFG;AAGH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,+BAA+B,CAAC;AAW/D,MAAM,WAAW,wBAAwB;IACvC,gEAAgE;IAChE,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B;;;;OAIG;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B;;;;;;OAMG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,gFAAgF;IAChF,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IACtB,kDAAkD;IAClD,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,4EAA4E;IAC5E,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB;0DACsD;IACtD,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B;;;;;;;OAOG;IACH,QAAQ,CAAC,yBAAyB,CAAC,EAAE,OAAO,CAAC;IAC7C,qEAAqE;IACrE,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,iEAAiE;IACjE,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,KAAK,CAAC;CAChC;AAED,yCAAyC;AACzC,MAAM,WAAW,cAAc;IAC7B,iCAAiC;IACjC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,2DAA2D;IAC3D,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,kCAAkC;IAClC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,yCAAyC;IACzC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B;;;;;;;OAOG;IACH,QAAQ,CAAC,iBAAiB,EAAE,OAAO,CAAC;IACpC,sCAAsC;IACtC,QAAQ,CAAC,mBAAmB,CAAC,EAAE,OAAO,CAAC;CACxC;AAED,0CAA0C;AAC1C,MAAM,WAAW,WAAW;IAC1B,IAAI,CAAC,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;CAClD;AAED,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,wBAAwB,GAAG,WAAW,CAsGhF"}
|