@openwop/openwop 1.1.2 → 1.1.5

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/index.d.ts CHANGED
@@ -12,10 +12,10 @@
12
12
  export { OpenwopClient } from './client.js';
13
13
  export type { OpenwopClientOptions, MutationOptions } from './client.js';
14
14
  export { WopError } from './types.js';
15
- export type { AuditVerifyAnomaly, AuditVerifyCheckpoint, AuditVerifyResult, BulkCancelRunResult, BulkCancelRunsRequest, BulkCancelRunsResponse, Capabilities, CancelRunRequest, CancelRunResponse, CreateRunRequest, CreateRunResponse, ErrorEnvelope, ForkRunRequest, ForkRunResponse, DebugBundle, DebugBundleOptions, RegisterWebhookRequest, RegisterWebhookResponse, InterruptByTokenInspection, PauseRunRequest, PauseRunResponse, PollEventsResponse, ResolveInterruptByTokenResponse, ResolveInterruptRequest, ResolveInterruptResponse, ResumeRunRequest, ResumeRunResponse, RunConfigurable, RunEventDoc, RunSnapshot, RunStatus, StreamMode, TypedRunEvent, AgentReasonedPayload, AgentReasoningDeltaPayload, AgentToolCalledPayload, AgentToolReturnedPayload, AgentHandoffPayload, AgentDecidedPayload, GetPromptRequest, ListPromptsRequest, ListPromptsResponse, PromptKind, PromptRef, PromptTemplate, PromptVariable, RenderPromptRequest, RenderPromptResponse, } from './types.js';
15
+ export type { AuditVerifyAnomaly, AuditVerifyCheckpoint, AuditVerifyResult, BulkCancelRunResult, BulkCancelRunsRequest, BulkCancelRunsResponse, Capabilities, CancelRunRequest, CancelRunResponse, CreateRunRequest, CreateRunResponse, ErrorEnvelope, ForkRunRequest, ForkRunResponse, DebugBundle, DebugBundleOptions, RegisterWebhookRequest, RegisterWebhookResponse, InterruptByTokenInspection, PauseRunRequest, PauseRunResponse, PollEventsResponse, ResolveInterruptByTokenResponse, ResolveInterruptRequest, ResolveInterruptResponse, ResumeRunRequest, ResumeRunResponse, RunConfigurable, RunDiffEventDiff, RunDiffResponse, RunEventDoc, RunSnapshot, RunStatus, StreamMode, TypedRunEvent, WorkspaceFile, PutWorkspaceFileRequest, AgentReasonedPayload, AgentReasoningDeltaPayload, AgentToolCalledPayload, AgentToolReturnedPayload, AgentHandoffPayload, AgentDecidedPayload, MemoryWrittenPayload, GetPromptRequest, ListPromptsRequest, ListPromptsResponse, PromptKind, PromptRef, PromptTemplate, PromptVariable, RenderPromptRequest, RenderPromptResponse, } from './types.js';
16
16
  export { streamEvents } from './sse.js';
17
17
  export type { EventsStreamContext, EventsStreamOptions } from './sse.js';
18
- export { isAgentReasoned, isAgentReasoningDelta, isAgentToolCalled, isAgentToolReturned, isAgentHandoff, isAgentDecided, subscribeToAgentReasoning, } from './event-helpers.js';
18
+ export { isAgentReasoned, isAgentReasoningDelta, isAgentToolCalled, isAgentToolReturned, isAgentHandoff, isAgentDecided, isMemoryWritten, subscribeToAgentReasoning, } from './event-helpers.js';
19
19
  export type { AgentReasoningCallbacks, Unsubscribe, } from './event-helpers.js';
20
20
  export { ACTIVE_RUN_STATUSES, TERMINAL_RUN_STATUSES, isTerminalRunStatus, HTTP_ERROR_CODES, isHttpErrorCode, RUN_ERROR_CODES, isRunErrorCode, } from './run-helpers.js';
21
21
  export type { ActiveRunStatus, TerminalRunStatus, HttpErrorCode, RunErrorCode, RunError, } from './run-helpers.js';
@@ -26,4 +26,8 @@ export type { VerifyWebhookSignatureOptions, VerifyWebhookOutcome, } from './web
26
26
  export { RegistryClient } from './registry-helpers.js';
27
27
  export type { RegistryClientOptions, RegistryDiscovery, RegistryIndex, RegistryIndexEntry, RegistryPackMetadata, RegistryVersionManifest, } from './registry-helpers.js';
28
28
  export type { AIEnvelope, AIEnvelopeErrorPayload, ClarificationRequestPayload, EnvelopeContract, EnvelopeContractRefusal, EnvelopeContractsCapability, EnvelopeMeta, EnvelopeOutcome, EnvelopeStrictness, PartialInfo, SchemaRequestPayload, SchemaResponsePayload, ValidationDetail, } from './types.js';
29
+ export { buildReasoningDirective } from './envelope-directive.js';
30
+ export type { ReasoningDirectiveStrength } from './envelope-directive.js';
31
+ export { parseRefusal } from './parse-refusal.js';
32
+ export type { RefusalProvider, RefusalSignal } from './parse-refusal.js';
29
33
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,YAAY,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACzE,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,YAAY,EACV,kBAAkB,EAClB,qBAAqB,EACrB,iBAAiB,EACjB,mBAAmB,EACnB,qBAAqB,EACrB,sBAAsB,EACtB,YAAY,EACZ,gBAAgB,EAChB,iBAAiB,EACjB,gBAAgB,EAChB,iBAAiB,EACjB,aAAa,EACb,cAAc,EACd,eAAe,EACf,WAAW,EACX,kBAAkB,EAClB,sBAAsB,EACtB,uBAAuB,EACvB,0BAA0B,EAC1B,eAAe,EACf,gBAAgB,EAChB,kBAAkB,EAClB,+BAA+B,EAC/B,uBAAuB,EACvB,wBAAwB,EACxB,gBAAgB,EAChB,iBAAiB,EACjB,eAAe,EACf,WAAW,EACX,WAAW,EACX,SAAS,EACT,UAAU,EACV,aAAa,EACb,oBAAoB,EACpB,0BAA0B,EAC1B,sBAAsB,EACtB,wBAAwB,EACxB,mBAAmB,EACnB,mBAAmB,EAEnB,gBAAgB,EAChB,kBAAkB,EAClB,mBAAmB,EACnB,UAAU,EACV,SAAS,EACT,cAAc,EACd,cAAc,EACd,mBAAmB,EACnB,oBAAoB,GACrB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AACxC,YAAY,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AAIzE,OAAO,EACL,eAAe,EACf,qBAAqB,EACrB,iBAAiB,EACjB,mBAAmB,EACnB,cAAc,EACd,cAAc,EACd,yBAAyB,GAC1B,MAAM,oBAAoB,CAAC;AAC5B,YAAY,EACV,uBAAuB,EACvB,WAAW,GACZ,MAAM,oBAAoB,CAAC;AAK5B,OAAO,EACL,mBAAmB,EACnB,qBAAqB,EACrB,mBAAmB,EACnB,gBAAgB,EAChB,eAAe,EACf,eAAe,EACf,cAAc,GACf,MAAM,kBAAkB,CAAC;AAC1B,YAAY,EACV,eAAe,EACf,iBAAiB,EACjB,aAAa,EACb,YAAY,EACZ,QAAQ,GACT,MAAM,kBAAkB,CAAC;AAM1B,OAAO,EACL,4BAA4B,EAC5B,sBAAsB,GACvB,MAAM,uBAAuB,CAAC;AAC/B,YAAY,EAAE,wBAAwB,EAAE,MAAM,uBAAuB,CAAC;AAMtE,OAAO,EACL,wCAAwC,EACxC,sBAAsB,EACtB,mBAAmB,GACpB,MAAM,sBAAsB,CAAC;AAC9B,YAAY,EACV,6BAA6B,EAC7B,oBAAoB,GACrB,MAAM,sBAAsB,CAAC;AAK9B,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,YAAY,EACV,qBAAqB,EACrB,iBAAiB,EACjB,aAAa,EACb,kBAAkB,EAClB,oBAAoB,EACpB,uBAAuB,GACxB,MAAM,uBAAuB,CAAC;AAI/B,YAAY,EACV,UAAU,EACV,sBAAsB,EACtB,2BAA2B,EAC3B,gBAAgB,EAChB,uBAAuB,EACvB,2BAA2B,EAC3B,YAAY,EACZ,eAAe,EACf,kBAAkB,EAClB,WAAW,EACX,oBAAoB,EACpB,qBAAqB,EACrB,gBAAgB,GACjB,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -14,7 +14,7 @@ export { WopError } from './types.js';
14
14
  export { streamEvents } from './sse.js';
15
15
  // RFC 0002 + RFC 0024 typed event helpers — type guards over `RunEventDoc`
16
16
  // plus a high-level streaming-reasoning subscription helper.
17
- export { isAgentReasoned, isAgentReasoningDelta, isAgentToolCalled, isAgentToolReturned, isAgentHandoff, isAgentDecided, subscribeToAgentReasoning, } from './event-helpers.js';
17
+ export { isAgentReasoned, isAgentReasoningDelta, isAgentToolCalled, isAgentToolReturned, isAgentHandoff, isAgentDecided, isMemoryWritten, subscribeToAgentReasoning, } from './event-helpers.js';
18
18
  // Run-status + run-error helpers (added in 1). Forward-compat predicates
19
19
  // over the wire-format unions declared above; full design + rationale in
20
20
  // `run-helpers.ts`.
@@ -33,4 +33,21 @@ export { DEFAULT_WEBHOOK_FRESHNESS_WINDOW_SECONDS, verifyWebhookSignature, signW
33
33
  // typed client for the public node-pack registry at packs.openwop.dev
34
34
  // per spec/v1/registry-operations.md.
35
35
  export { RegistryClient } from './registry-helpers.js';
36
+ // RFC 0030 §A `reasoning` field prompt-directive helper. Hosts that
37
+ // advertise `capabilities.envelopes.reasoning.supported: true` use this
38
+ // to synthesize the system-prompt fragment that instructs the model to
39
+ // populate the OPTIONAL `reasoning` field. See `envelope-directive.ts`
40
+ // for the operational note on `"mandatory"` strength (provider-side
41
+ // refusal risk per the 2026-05-21 RFC 0030 amendment).
42
+ export { buildReasoningDirective } from './envelope-directive.js';
43
+ // RFC 0032 §B.3 + RFC 0033 §D refusal detection helper. Normalizes
44
+ // per-provider safety-stop signals (Anthropic `stop_reason: "refusal"`,
45
+ // OpenAI `message.refusal` + `finish_reason: "content_filter"`, Gemini
46
+ // `finishReason: "SAFETY"` + `promptFeedback.blockReason: "SAFETY"`)
47
+ // to a canonical `{ refusalText, safetyCategory?, provider }` shape.
48
+ // Hosts route the non-null return through `envelope.refusal` emission
49
+ // + the `envelope_refusal` terminal error code (RFC 0033 §F).
50
+ // **SECURITY:** Pass `refusalText` through the BYOK redaction harness
51
+ // BEFORE persistence — this helper does NOT redact.
52
+ export { parseRefusal } from './parse-refusal.js';
36
53
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAoDtC,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAGxC,2EAA2E;AAC3E,6DAA6D;AAC7D,OAAO,EACL,eAAe,EACf,qBAAqB,EACrB,iBAAiB,EACjB,mBAAmB,EACnB,cAAc,EACd,cAAc,EACd,yBAAyB,GAC1B,MAAM,oBAAoB,CAAC;AAM5B,yEAAyE;AACzE,yEAAyE;AACzE,oBAAoB;AACpB,OAAO,EACL,mBAAmB,EACnB,qBAAqB,EACrB,mBAAmB,EACnB,gBAAgB,EAChB,eAAe,EACf,eAAe,EACf,cAAc,GACf,MAAM,kBAAkB,CAAC;AAS1B,iDAAiD;AACjD,sEAAsE;AACtE,mEAAmE;AACnE,uDAAuD;AACvD,OAAO,EACL,4BAA4B,EAC5B,sBAAsB,GACvB,MAAM,uBAAuB,CAAC;AAG/B,sEAAsE;AACtE,4DAA4D;AAC5D,sEAAsE;AACtE,uDAAuD;AACvD,OAAO,EACL,wCAAwC,EACxC,sBAAsB,EACtB,mBAAmB,GACpB,MAAM,sBAAsB,CAAC;AAM9B,uEAAuE;AACvE,sEAAsE;AACtE,sCAAsC;AACtC,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AA0DtC,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAGxC,2EAA2E;AAC3E,6DAA6D;AAC7D,OAAO,EACL,eAAe,EACf,qBAAqB,EACrB,iBAAiB,EACjB,mBAAmB,EACnB,cAAc,EACd,cAAc,EACd,eAAe,EACf,yBAAyB,GAC1B,MAAM,oBAAoB,CAAC;AAM5B,yEAAyE;AACzE,yEAAyE;AACzE,oBAAoB;AACpB,OAAO,EACL,mBAAmB,EACnB,qBAAqB,EACrB,mBAAmB,EACnB,gBAAgB,EAChB,eAAe,EACf,eAAe,EACf,cAAc,GACf,MAAM,kBAAkB,CAAC;AAS1B,iDAAiD;AACjD,sEAAsE;AACtE,mEAAmE;AACnE,uDAAuD;AACvD,OAAO,EACL,4BAA4B,EAC5B,sBAAsB,GACvB,MAAM,uBAAuB,CAAC;AAG/B,sEAAsE;AACtE,4DAA4D;AAC5D,sEAAsE;AACtE,uDAAuD;AACvD,OAAO,EACL,wCAAwC,EACxC,sBAAsB,EACtB,mBAAmB,GACpB,MAAM,sBAAsB,CAAC;AAM9B,uEAAuE;AACvE,sEAAsE;AACtE,sCAAsC;AACtC,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AA4BvD,oEAAoE;AACpE,wEAAwE;AACxE,uEAAuE;AACvE,uEAAuE;AACvE,oEAAoE;AACpE,uDAAuD;AACvD,OAAO,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AAGlE,mEAAmE;AACnE,wEAAwE;AACxE,uEAAuE;AACvE,qEAAqE;AACrE,qEAAqE;AACrE,sEAAsE;AACtE,8DAA8D;AAC9D,sEAAsE;AACtE,oDAAoD;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC"}
@@ -0,0 +1,114 @@
1
+ /**
2
+ * parseRefusal — normalize per-provider LLM safety-stop signals to the
3
+ * canonical RFC 0032 §B.3 refusal shape.
4
+ *
5
+ * The three Tier-1 vendors (Anthropic / OpenAI / Google Gemini) surface
6
+ * refusals through different fields:
7
+ *
8
+ * - **Anthropic Messages API**: `stop_reason: "refusal"` (their 2025
9
+ * release) OR `stop_reason: "end_turn"` accompanied by safety-stop
10
+ * markers in the content. Refusal text MAY be inline in the
11
+ * `content[]` array's text blocks.
12
+ * - **OpenAI Chat Completions**: `choices[0].finish_reason:
13
+ * "content_filter"` OR `choices[0].message.refusal: <string>` (the
14
+ * refusal-text field added in their structured-output release).
15
+ * - **Google Gemini**: `candidates[0].finishReason: "SAFETY"` OR
16
+ * `promptFeedback.blockReason: "SAFETY"` (input-side block).
17
+ *
18
+ * Without normalization, every host re-implements this detection. This
19
+ * helper consolidates the per-vendor shape-detection and returns a
20
+ * canonical `RefusalSignal | null` — null when the response is a
21
+ * normal completion (no refusal detected).
22
+ *
23
+ * Per RFC 0032 §B.3 + RFC 0033 §D, hosts MUST NOT retry on refusal
24
+ * (circumvention concern). Callers route the non-null return through
25
+ * `envelope.refusal` emission + the `envelope_refusal` terminal error
26
+ * code (per RFC 0033 §F).
27
+ *
28
+ * Per SECURITY/invariants.yaml §envelope-refusal-no-prompt-leak,
29
+ * `refusalText` MUST be passed through the host's BYOK redaction
30
+ * harness BEFORE persistence — this helper does NOT redact; the
31
+ * caller is responsible for SR-1 carry-forward.
32
+ *
33
+ * @see RFCS/0032-envelope-reliability-events.md §B.3
34
+ * @see RFCS/0033-envelope-completion-contract.md §D + §F
35
+ * @see SECURITY/invariants.yaml §envelope-refusal-no-prompt-leak
36
+ */
37
+ /**
38
+ * Provider identifier for the matched shape. `"unknown"` is reserved
39
+ * for refusals matched on heuristic signals without a definitive
40
+ * vendor-shape match.
41
+ */
42
+ export type RefusalProvider = 'anthropic' | 'openai' | 'google' | 'unknown';
43
+ /**
44
+ * Canonical refusal signal. All three Tier-1 vendor shapes normalize
45
+ * to this form. `null` from `parseRefusal()` means "no refusal detected"
46
+ * (a normal completion); a non-null `RefusalSignal` means the caller
47
+ * SHOULD route through the RFC 0032 §B.3 refusal-emission path.
48
+ */
49
+ export interface RefusalSignal {
50
+ /**
51
+ * The provider's refusal text, when surfaced. MAY be `null` even for
52
+ * detected refusals — Anthropic + Gemini frequently refuse without
53
+ * inline text (the safety filter is opaque to the model). OpenAI's
54
+ * `message.refusal` field is the most consistent source of human-
55
+ * readable refusal text.
56
+ *
57
+ * **SECURITY:** When non-null, `refusalText` MAY contain prompt
58
+ * content that triggered the safety filter. Callers MUST pass it
59
+ * through their BYOK + prompt-content redaction harness BEFORE
60
+ * persistence (per `envelope-refusal-no-prompt-leak` SECURITY
61
+ * invariant).
62
+ */
63
+ refusalText: string | null;
64
+ /**
65
+ * Provider-specific safety-category identifier, when surfaced.
66
+ * Examples: Gemini's safety-rating categories
67
+ * (`HARM_CATEGORY_HARASSMENT`, etc.), OpenAI's content-filter category,
68
+ * Anthropic's policy-violation tag. Hosts MAY echo this on the
69
+ * `envelope.refusal.safetyCategory` event field for downstream
70
+ * observability.
71
+ */
72
+ safetyCategory?: string;
73
+ /**
74
+ * Which provider's shape was matched. Useful for debugging
75
+ * cross-host integration + for hosts that want to route refusals
76
+ * differently per vendor (e.g., different operator notifications).
77
+ */
78
+ provider: RefusalProvider;
79
+ }
80
+ /**
81
+ * Parse a provider response into a canonical refusal signal.
82
+ *
83
+ * Returns `null` when no refusal is detected (normal completion).
84
+ * Returns a `RefusalSignal` when the response matches one of the
85
+ * three Tier-1 vendors' safety-stop shapes.
86
+ *
87
+ * Detection order: OpenAI → Anthropic → Gemini. Each detector inspects
88
+ * a distinctive top-level field, so cross-vendor false-positives are
89
+ * unlikely. A response that doesn't match any vendor shape returns
90
+ * `null` (hosts that route through novel providers add their own
91
+ * detector + fall back to this for the three known ones).
92
+ *
93
+ * @example
94
+ * ```ts
95
+ * import { parseRefusal } from '@openwop/openwop';
96
+ *
97
+ * const response = await callOpenAI({...});
98
+ * const refusal = parseRefusal(response);
99
+ * if (refusal) {
100
+ * // Route through envelope.refusal emission + envelope_refusal error code.
101
+ * // REMEMBER to redact refusalText through the BYOK harness before
102
+ * // persistence (SECURITY invariant envelope-refusal-no-prompt-leak).
103
+ * await emitEnvelopeRefusal({
104
+ * refusalText: redactBYOK(refusal.refusalText),
105
+ * safetyCategory: refusal.safetyCategory,
106
+ * provider: refusal.provider,
107
+ * });
108
+ * throw new EnvelopeRefusalError(...);
109
+ * }
110
+ * // ...normal-completion handling...
111
+ * ```
112
+ */
113
+ export declare function parseRefusal(providerResponse: unknown): RefusalSignal | null;
114
+ //# sourceMappingURL=parse-refusal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parse-refusal.d.ts","sourceRoot":"","sources":["../src/parse-refusal.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAEH;;;;GAIG;AACH,MAAM,MAAM,eAAe,GAAG,WAAW,GAAG,QAAQ,GAAG,QAAQ,GAAG,SAAS,CAAC;AAE5E;;;;;GAKG;AACH,MAAM,WAAW,aAAa;IAC5B;;;;;;;;;;;;OAYG;IACH,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAE3B;;;;;;;OAOG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB;;;;OAIG;IACH,QAAQ,EAAE,eAAe,CAAC;CAC3B;AA6LD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,wBAAgB,YAAY,CAAC,gBAAgB,EAAE,OAAO,GAAG,aAAa,GAAG,IAAI,CAM5E"}
@@ -0,0 +1,216 @@
1
+ /**
2
+ * parseRefusal — normalize per-provider LLM safety-stop signals to the
3
+ * canonical RFC 0032 §B.3 refusal shape.
4
+ *
5
+ * The three Tier-1 vendors (Anthropic / OpenAI / Google Gemini) surface
6
+ * refusals through different fields:
7
+ *
8
+ * - **Anthropic Messages API**: `stop_reason: "refusal"` (their 2025
9
+ * release) OR `stop_reason: "end_turn"` accompanied by safety-stop
10
+ * markers in the content. Refusal text MAY be inline in the
11
+ * `content[]` array's text blocks.
12
+ * - **OpenAI Chat Completions**: `choices[0].finish_reason:
13
+ * "content_filter"` OR `choices[0].message.refusal: <string>` (the
14
+ * refusal-text field added in their structured-output release).
15
+ * - **Google Gemini**: `candidates[0].finishReason: "SAFETY"` OR
16
+ * `promptFeedback.blockReason: "SAFETY"` (input-side block).
17
+ *
18
+ * Without normalization, every host re-implements this detection. This
19
+ * helper consolidates the per-vendor shape-detection and returns a
20
+ * canonical `RefusalSignal | null` — null when the response is a
21
+ * normal completion (no refusal detected).
22
+ *
23
+ * Per RFC 0032 §B.3 + RFC 0033 §D, hosts MUST NOT retry on refusal
24
+ * (circumvention concern). Callers route the non-null return through
25
+ * `envelope.refusal` emission + the `envelope_refusal` terminal error
26
+ * code (per RFC 0033 §F).
27
+ *
28
+ * Per SECURITY/invariants.yaml §envelope-refusal-no-prompt-leak,
29
+ * `refusalText` MUST be passed through the host's BYOK redaction
30
+ * harness BEFORE persistence — this helper does NOT redact; the
31
+ * caller is responsible for SR-1 carry-forward.
32
+ *
33
+ * @see RFCS/0032-envelope-reliability-events.md §B.3
34
+ * @see RFCS/0033-envelope-completion-contract.md §D + §F
35
+ * @see SECURITY/invariants.yaml §envelope-refusal-no-prompt-leak
36
+ */
37
+ /**
38
+ * Try to parse the response as OpenAI Chat Completions output.
39
+ *
40
+ * Detection: top-level `choices` array. Refusal signals:
41
+ * - `choices[0].finish_reason === "content_filter"`
42
+ * - `choices[0].message.refusal` is a non-empty string
43
+ */
44
+ function tryParseOpenAI(response) {
45
+ if (!response || typeof response !== 'object')
46
+ return null;
47
+ const r = response;
48
+ if (!Array.isArray(r.choices) || r.choices.length === 0)
49
+ return null;
50
+ const choice = r.choices[0];
51
+ if (!choice || typeof choice !== 'object')
52
+ return null;
53
+ const finishReason = choice.finish_reason;
54
+ const message = choice.message;
55
+ const refusalField = message && typeof message === 'object' ? message.refusal : undefined;
56
+ // Primary signal: explicit refusal-text field. OpenAI's structured-output
57
+ // release populates this when the safety filter intervenes.
58
+ if (typeof refusalField === 'string' && refusalField.length > 0) {
59
+ return { refusalText: refusalField, provider: 'openai' };
60
+ }
61
+ // Secondary signal: finish_reason. content_filter is the canonical
62
+ // safety-stop value.
63
+ if (finishReason === 'content_filter') {
64
+ const text = message && typeof message === 'object' && typeof message.content === 'string'
65
+ ? message.content
66
+ : null;
67
+ return { refusalText: text, safetyCategory: 'content_filter', provider: 'openai' };
68
+ }
69
+ return null;
70
+ }
71
+ /**
72
+ * Try to parse the response as Anthropic Messages API output.
73
+ *
74
+ * Detection: top-level `stop_reason` field (Anthropic's distinctive
75
+ * marker). Refusal signals:
76
+ * - `stop_reason === "refusal"` (their 2025 release)
77
+ *
78
+ * Anthropic does not surface a distinct safety-category field on
79
+ * refusals; the `refusal` stop_reason is the binary signal.
80
+ */
81
+ function tryParseAnthropic(response) {
82
+ if (!response || typeof response !== 'object')
83
+ return null;
84
+ const r = response;
85
+ if (typeof r.stop_reason !== 'string')
86
+ return null;
87
+ if (r.stop_reason === 'refusal') {
88
+ // Extract refusal text from the content array (Anthropic returns an
89
+ // array of typed blocks; refusal text appears in `text`-type blocks).
90
+ let refusalText = null;
91
+ if (Array.isArray(r.content)) {
92
+ const textBlocks = [];
93
+ for (const block of r.content) {
94
+ if (block && typeof block === 'object') {
95
+ const b = block;
96
+ if (b.type === 'text' && typeof b.text === 'string') {
97
+ textBlocks.push(b.text);
98
+ }
99
+ }
100
+ }
101
+ if (textBlocks.length > 0)
102
+ refusalText = textBlocks.join('\n');
103
+ }
104
+ return { refusalText, provider: 'anthropic' };
105
+ }
106
+ return null;
107
+ }
108
+ /**
109
+ * Try to parse the response as Google Gemini `generateContent` output.
110
+ *
111
+ * Detection: top-level `candidates` array OR top-level `promptFeedback`
112
+ * object. Refusal signals:
113
+ * - `candidates[0].finishReason === "SAFETY"` (output-side block)
114
+ * - `promptFeedback.blockReason === "SAFETY"` (input-side block)
115
+ *
116
+ * Gemini surfaces safety categories on `safetyRatings[]`; this helper
117
+ * picks the highest-probability HIGH/MEDIUM-tier category as
118
+ * `safetyCategory` when available.
119
+ */
120
+ function tryParseGemini(response) {
121
+ if (!response || typeof response !== 'object')
122
+ return null;
123
+ const r = response;
124
+ // Output-side safety block.
125
+ if (Array.isArray(r.candidates) && r.candidates.length > 0) {
126
+ const candidate = r.candidates[0];
127
+ if (candidate && typeof candidate === 'object' && candidate.finishReason === 'SAFETY') {
128
+ const safetyCategory = extractGeminiHighestRiskCategory(candidate.safetyRatings);
129
+ const result = { refusalText: null, provider: 'google' };
130
+ if (safetyCategory !== undefined)
131
+ result.safetyCategory = safetyCategory;
132
+ return result;
133
+ }
134
+ }
135
+ // Input-side safety block (Gemini rejected the prompt itself).
136
+ if (r.promptFeedback && typeof r.promptFeedback === 'object') {
137
+ const pf = r.promptFeedback;
138
+ if (typeof pf.blockReason === 'string' && pf.blockReason.toUpperCase().includes('SAFETY')) {
139
+ const safetyCategory = extractGeminiHighestRiskCategory(pf.safetyRatings);
140
+ const result = { refusalText: null, provider: 'google' };
141
+ if (safetyCategory !== undefined)
142
+ result.safetyCategory = safetyCategory;
143
+ return result;
144
+ }
145
+ }
146
+ return null;
147
+ }
148
+ /**
149
+ * From a Gemini `safetyRatings[]` array, return the highest-probability
150
+ * non-NEGLIGIBLE category identifier. Returns `undefined` when the
151
+ * array is absent or all ratings are NEGLIGIBLE.
152
+ */
153
+ function extractGeminiHighestRiskCategory(safetyRatings) {
154
+ if (!Array.isArray(safetyRatings))
155
+ return undefined;
156
+ const PROBABILITY_RANK = {
157
+ HIGH: 3,
158
+ MEDIUM: 2,
159
+ LOW: 1,
160
+ NEGLIGIBLE: 0,
161
+ };
162
+ let best = null;
163
+ for (const rating of safetyRatings) {
164
+ if (!rating || typeof rating !== 'object')
165
+ continue;
166
+ const r = rating;
167
+ if (typeof r.category !== 'string' || typeof r.probability !== 'string')
168
+ continue;
169
+ const rank = PROBABILITY_RANK[r.probability.toUpperCase()] ?? 0;
170
+ if (rank === 0)
171
+ continue;
172
+ if (best === null || rank > best.rank) {
173
+ best = { category: r.category, rank };
174
+ }
175
+ }
176
+ return best?.category;
177
+ }
178
+ /**
179
+ * Parse a provider response into a canonical refusal signal.
180
+ *
181
+ * Returns `null` when no refusal is detected (normal completion).
182
+ * Returns a `RefusalSignal` when the response matches one of the
183
+ * three Tier-1 vendors' safety-stop shapes.
184
+ *
185
+ * Detection order: OpenAI → Anthropic → Gemini. Each detector inspects
186
+ * a distinctive top-level field, so cross-vendor false-positives are
187
+ * unlikely. A response that doesn't match any vendor shape returns
188
+ * `null` (hosts that route through novel providers add their own
189
+ * detector + fall back to this for the three known ones).
190
+ *
191
+ * @example
192
+ * ```ts
193
+ * import { parseRefusal } from '@openwop/openwop';
194
+ *
195
+ * const response = await callOpenAI({...});
196
+ * const refusal = parseRefusal(response);
197
+ * if (refusal) {
198
+ * // Route through envelope.refusal emission + envelope_refusal error code.
199
+ * // REMEMBER to redact refusalText through the BYOK harness before
200
+ * // persistence (SECURITY invariant envelope-refusal-no-prompt-leak).
201
+ * await emitEnvelopeRefusal({
202
+ * refusalText: redactBYOK(refusal.refusalText),
203
+ * safetyCategory: refusal.safetyCategory,
204
+ * provider: refusal.provider,
205
+ * });
206
+ * throw new EnvelopeRefusalError(...);
207
+ * }
208
+ * // ...normal-completion handling...
209
+ * ```
210
+ */
211
+ export function parseRefusal(providerResponse) {
212
+ return (tryParseOpenAI(providerResponse) ??
213
+ tryParseAnthropic(providerResponse) ??
214
+ tryParseGemini(providerResponse));
215
+ }
216
+ //# sourceMappingURL=parse-refusal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parse-refusal.js","sourceRoot":"","sources":["../src/parse-refusal.ts"],"names":[],"mappings":"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"}
package/dist/types.d.ts CHANGED
@@ -21,6 +21,10 @@ export interface Capabilities {
21
21
  schemaRounds: number;
22
22
  envelopesPerTurn: number;
23
23
  maxNodeExecutions?: number;
24
+ /** RFC 0058. Engine-side wall-clock ceiling per run (ms); upper bound for `RunConfigurable.runTimeoutMs`. */
25
+ maxRunDurationMs?: number;
26
+ /** RFC 0058. Engine-side agent-loop iteration ceiling; upper bound for `RunConfigurable.maxLoopIterations`. */
27
+ maxLoopIterations?: number;
24
28
  };
25
29
  extensions?: Record<string, unknown>;
26
30
  implementation?: {
@@ -35,6 +39,12 @@ export interface Capabilities {
35
39
  observability?: Record<string, unknown>;
36
40
  minClientVersion?: string;
37
41
  }
42
+ /**
43
+ * The `kind` discriminator on a `cap.breached` event payload
44
+ * (`run-event-payloads.schema.json#capBreached`). The four engine kinds, the
45
+ * RFC 0008 §K `wasm-*` runtime caps, and the RFC 0058 run-scoped bounds.
46
+ */
47
+ export type CapBreachedKind = 'clarification' | 'schema' | 'envelopes' | 'node-executions' | 'wasm-memory' | 'wasm-fuel' | 'wasm-execution-time' | 'run-duration' | 'loop-iterations';
38
48
  export interface RunSnapshot {
39
49
  runId: string;
40
50
  workflowId: string;
@@ -76,6 +86,15 @@ export interface RunSnapshot {
76
86
  export interface RunConfigurable {
77
87
  /** Override the per-run node-execution ceiling. Clamped server-side. */
78
88
  recursionLimit?: number;
89
+ /** RFC 0058. Wall-clock run deadline (ms from `run.started`); clamped to
90
+ * `Capabilities.limits.maxRunDurationMs`. Breach → `cap.breached
91
+ * { kind: 'run-duration' }` + `run_timeout`. */
92
+ runTimeoutMs?: number;
93
+ /** RFC 0058. Agent-loop iteration ceiling (one per orchestrator turn);
94
+ * clamped to `Capabilities.limits.maxLoopIterations`. Breach →
95
+ * `cap.breached { kind: 'loop-iterations' }` + `loop_limit_exceeded`.
96
+ * Ignored unless the host advertises `capabilities.agents.loop.supported`. */
97
+ maxLoopIterations?: number;
79
98
  /** Override AI model for nodes that consume `ctx.config.configurable.model`. */
80
99
  model?: string;
81
100
  /** Override AI temperature (server SHOULD enforce 0..2). */
@@ -229,6 +248,107 @@ export interface ForkRunResponse {
229
248
  status: RunStatus;
230
249
  eventsUrl: string;
231
250
  }
251
+ /** RFC 0056 — a non-blocking quality signal on a run/event/node. */
252
+ export type AnnotationSignal = {
253
+ kind: 'rating';
254
+ rating: number;
255
+ } | {
256
+ kind: 'flag';
257
+ } | {
258
+ kind: 'label';
259
+ label: string;
260
+ } | {
261
+ kind: 'correction';
262
+ correction: string;
263
+ };
264
+ /** RFC 0056 persisted annotation (`annotation.schema.json`). A side-resource —
265
+ * not a replayable run-event-log entry. */
266
+ export interface Annotation {
267
+ annotationId: string;
268
+ target: {
269
+ runId: string;
270
+ eventId?: string;
271
+ nodeId?: string;
272
+ };
273
+ signal: AnnotationSignal;
274
+ actor: {
275
+ principalRef: string;
276
+ };
277
+ note?: string;
278
+ createdAt: string;
279
+ }
280
+ /** RFC 0056 request body for `createAnnotation` (`annotation-create.schema.json`).
281
+ * The host assigns `annotationId`/`createdAt`/`actor` and binds `target.runId`. */
282
+ export interface CreateAnnotationRequest {
283
+ target?: {
284
+ eventId?: string;
285
+ nodeId?: string;
286
+ };
287
+ signal: AnnotationSignal;
288
+ note?: string;
289
+ }
290
+ /** RFC 0059 versioned, tenant·workspace-scoped ground-truth file
291
+ * (`workspace-file.schema.json`). The `list` endpoint returns this shape
292
+ * minus `content` (metadata only). */
293
+ export interface WorkspaceFile {
294
+ path: string;
295
+ content: string;
296
+ contentType?: string;
297
+ version: number;
298
+ etag?: string;
299
+ updatedAt: string;
300
+ }
301
+ /** RFC 0059 request body for `putWorkspaceFile` (`workspace-file-create.schema.json`).
302
+ * `path` is URL-bound; the host assigns `version`/`etag`/`updatedAt`.
303
+ * Optimistic concurrency is expressed via the `If-Match` header, not the body. */
304
+ export interface PutWorkspaceFileRequest {
305
+ content: string;
306
+ contentType?: string;
307
+ }
308
+ /**
309
+ * Response from `GET /v1/runs/{runId}/ancestry` — RFC 0040 §C cross-host
310
+ * composition parent. `parent: null` for top-level runs (not dispatched
311
+ * from any other run); otherwise `parent.wellKnownUrl` is set when the
312
+ * parent is on a different host so callers can walk the chain.
313
+ *
314
+ * Capability-gated: hosts not advertising
315
+ * `capabilities.multiAgent.executionModel.crossHostCausation.ancestryEndpointSupported: true`
316
+ * return 404; the SDK surfaces that as `null` via `runs.ancestry()`.
317
+ */
318
+ export interface RunAncestryResponse {
319
+ runId: string;
320
+ hostId: string;
321
+ parent: null | {
322
+ runId: string;
323
+ hostId: string;
324
+ wellKnownUrl?: string;
325
+ cause: 'mcp-tool-call' | 'a2a-message' | 'core.subWorkflow' | 'core.dispatch';
326
+ };
327
+ }
328
+ /** RFC 0054 — response from `GET /v1/runs/{runId}:diff?against={otherRunId}`.
329
+ * Mirror of `run-diff-response.schema.json`. Deterministic, replay-aware
330
+ * structured diff of two runs' event sequences + terminal states. */
331
+ export interface RunDiffEventDiff {
332
+ seq: number;
333
+ op: 'added' | 'removed' | 'changed';
334
+ /** Present unless `op === 'added'`. */
335
+ aEvent?: RunEventDoc;
336
+ /** Present unless `op === 'removed'`. */
337
+ bEvent?: RunEventDoc;
338
+ }
339
+ export interface RunDiffResponse {
340
+ /** The `{runId}` run. */
341
+ a: string;
342
+ /** The `against` run. */
343
+ b: string;
344
+ /** Sequence at which the logs first diverge; null if identical. */
345
+ divergedAtSeq: number | null;
346
+ eventDiffs: RunDiffEventDiff[];
347
+ /** Diff of terminal RunSnapshot states (redaction-safe). */
348
+ stateDiff: Record<string, unknown>;
349
+ /** True if either run was in-flight and only a prefix was compared. */
350
+ truncated?: boolean;
351
+ }
232
352
  export interface ResolveInterruptRequest {
233
353
  resumeValue: unknown;
234
354
  }
@@ -487,6 +607,18 @@ export interface AgentDecidedPayload {
487
607
  confidence?: number;
488
608
  [key: string]: unknown;
489
609
  }
610
+ /** `memory.written` payload (RFC 0057). Content-free per-write attribution:
611
+ * identifiers + non-secret tags only — never the entry content (the read
612
+ * side serves that, already SR-1-redacted). `nodeId` is omitted for host
613
+ * session-end writes with no node attribution. */
614
+ export interface MemoryWrittenPayload {
615
+ memoryRef: string;
616
+ memoryId: string;
617
+ nodeId?: string;
618
+ agentId?: string;
619
+ tags?: string[];
620
+ [key: string]: unknown;
621
+ }
490
622
  /** A `RunEventDoc` narrowed to a specific event-type discriminator +
491
623
  * payload shape. Returned by the `isAgent*` type guards in
492
624
  * `event-helpers.ts`. */
@@ -736,4 +868,33 @@ export declare class WopError extends Error {
736
868
  readonly traceId: string | undefined;
737
869
  constructor(status: number, rawText: string, envelope: ErrorEnvelope | undefined, traceparent: string | undefined);
738
870
  }
871
+ /**
872
+ * One installed manifest agent, as projected by `GET /v1/agents` /
873
+ * `GET /v1/agents/{agentId}` (RFC 0072 §A). Read-only — never carries the
874
+ * system-prompt body, resolved handoff schemas, or credential material (SR-1).
875
+ */
876
+ export interface AgentInventoryEntry {
877
+ agentId: string;
878
+ persona: string;
879
+ label: string;
880
+ description?: string;
881
+ modelClass: string;
882
+ packName: string;
883
+ packVersion: string;
884
+ toolAllowlist: string[];
885
+ hasHandoffSchemas: boolean;
886
+ memoryShape?: {
887
+ scratchpad?: boolean;
888
+ conversation?: boolean;
889
+ longTerm?: boolean;
890
+ };
891
+ confidenceThreshold?: number;
892
+ /** RFC 0072 §C — optional capability tiers this host does not satisfy, inert here. */
893
+ degraded?: string[];
894
+ }
895
+ /** Response body for `GET /v1/agents` (RFC 0072 §A). */
896
+ export interface AgentInventoryResponse {
897
+ agents: AgentInventoryEntry[];
898
+ total: number;
899
+ }
739
900
  //# sourceMappingURL=types.d.ts.map