agentfootprint 2.13.0 → 2.14.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/dist/adapters/llm/AnthropicProvider.js +69 -2
- package/dist/adapters/llm/AnthropicProvider.js.map +1 -1
- package/dist/adapters/llm/BrowserAnthropicProvider.js +110 -2
- package/dist/adapters/llm/BrowserAnthropicProvider.js.map +1 -1
- package/dist/conventions.js +13 -2
- package/dist/conventions.js.map +1 -1
- package/dist/core/Agent.js +47 -1
- package/dist/core/Agent.js.map +1 -1
- package/dist/core/agent/AgentBuilder.js +112 -1
- package/dist/core/agent/AgentBuilder.js.map +1 -1
- package/dist/core/agent/buildAgentChart.js +22 -3
- package/dist/core/agent/buildAgentChart.js.map +1 -1
- package/dist/core/agent/stages/callLLM.js +11 -0
- package/dist/core/agent/stages/callLLM.js.map +1 -1
- package/dist/core/agent/stages/prepareFinal.js +12 -1
- package/dist/core/agent/stages/prepareFinal.js.map +1 -1
- package/dist/core/agent/stages/seed.js +4 -0
- package/dist/core/agent/stages/seed.js.map +1 -1
- package/dist/core/agent/stages/toolCalls.js +7 -0
- package/dist/core/agent/stages/toolCalls.js.map +1 -1
- package/dist/core/slots/buildThinkingSubflow.js +112 -0
- package/dist/core/slots/buildThinkingSubflow.js.map +1 -0
- package/dist/esm/adapters/llm/AnthropicProvider.js +69 -2
- package/dist/esm/adapters/llm/AnthropicProvider.js.map +1 -1
- package/dist/esm/adapters/llm/BrowserAnthropicProvider.js +110 -2
- package/dist/esm/adapters/llm/BrowserAnthropicProvider.js.map +1 -1
- package/dist/esm/conventions.js +13 -2
- package/dist/esm/conventions.js.map +1 -1
- package/dist/esm/core/Agent.js +47 -1
- package/dist/esm/core/Agent.js.map +1 -1
- package/dist/esm/core/agent/AgentBuilder.js +112 -1
- package/dist/esm/core/agent/AgentBuilder.js.map +1 -1
- package/dist/esm/core/agent/buildAgentChart.js +22 -3
- package/dist/esm/core/agent/buildAgentChart.js.map +1 -1
- package/dist/esm/core/agent/stages/callLLM.js +11 -0
- package/dist/esm/core/agent/stages/callLLM.js.map +1 -1
- package/dist/esm/core/agent/stages/prepareFinal.js +12 -1
- package/dist/esm/core/agent/stages/prepareFinal.js.map +1 -1
- package/dist/esm/core/agent/stages/seed.js +4 -0
- package/dist/esm/core/agent/stages/seed.js.map +1 -1
- package/dist/esm/core/agent/stages/toolCalls.js +7 -0
- package/dist/esm/core/agent/stages/toolCalls.js.map +1 -1
- package/dist/esm/core/slots/buildThinkingSubflow.js +108 -0
- package/dist/esm/core/slots/buildThinkingSubflow.js.map +1 -0
- package/dist/esm/events/registry.js +6 -0
- package/dist/esm/events/registry.js.map +1 -1
- package/dist/esm/recorders/observability/BoundaryRecorder.js +27 -2
- package/dist/esm/recorders/observability/BoundaryRecorder.js.map +1 -1
- package/dist/esm/recorders/observability/FlowchartRecorder.js +29 -0
- package/dist/esm/recorders/observability/FlowchartRecorder.js.map +1 -1
- package/dist/esm/security/index.js +1 -0
- package/dist/esm/security/index.js.map +1 -1
- package/dist/esm/security/thinkingRedaction.js +66 -0
- package/dist/esm/security/thinkingRedaction.js.map +1 -0
- package/dist/esm/thinking/AnthropicThinkingHandler.js +111 -0
- package/dist/esm/thinking/AnthropicThinkingHandler.js.map +1 -0
- package/dist/esm/thinking/MockThinkingHandler.js +94 -0
- package/dist/esm/thinking/MockThinkingHandler.js.map +1 -0
- package/dist/esm/thinking/OpenAIThinkingHandler.js +72 -0
- package/dist/esm/thinking/OpenAIThinkingHandler.js.map +1 -0
- package/dist/esm/thinking/index.js +51 -0
- package/dist/esm/thinking/index.js.map +1 -0
- package/dist/esm/thinking/registry.js +46 -0
- package/dist/esm/thinking/registry.js.map +1 -0
- package/dist/esm/thinking/types.js +30 -0
- package/dist/esm/thinking/types.js.map +1 -0
- package/dist/events/registry.js +6 -0
- package/dist/events/registry.js.map +1 -1
- package/dist/recorders/observability/BoundaryRecorder.js +27 -2
- package/dist/recorders/observability/BoundaryRecorder.js.map +1 -1
- package/dist/recorders/observability/FlowchartRecorder.js +29 -0
- package/dist/recorders/observability/FlowchartRecorder.js.map +1 -1
- package/dist/security/index.js +4 -1
- package/dist/security/index.js.map +1 -1
- package/dist/security/thinkingRedaction.js +70 -0
- package/dist/security/thinkingRedaction.js.map +1 -0
- package/dist/thinking/AnthropicThinkingHandler.js +114 -0
- package/dist/thinking/AnthropicThinkingHandler.js.map +1 -0
- package/dist/thinking/MockThinkingHandler.js +99 -0
- package/dist/thinking/MockThinkingHandler.js.map +1 -0
- package/dist/thinking/OpenAIThinkingHandler.js +75 -0
- package/dist/thinking/OpenAIThinkingHandler.js.map +1 -0
- package/dist/thinking/index.js +61 -0
- package/dist/thinking/index.js.map +1 -0
- package/dist/thinking/registry.js +50 -0
- package/dist/thinking/registry.js.map +1 -0
- package/dist/thinking/types.js +31 -0
- package/dist/thinking/types.js.map +1 -0
- package/dist/types/adapters/llm/AnthropicProvider.d.ts +11 -0
- package/dist/types/adapters/llm/AnthropicProvider.d.ts.map +1 -1
- package/dist/types/adapters/llm/BrowserAnthropicProvider.d.ts.map +1 -1
- package/dist/types/adapters/types.d.ts +97 -0
- package/dist/types/adapters/types.d.ts.map +1 -1
- package/dist/types/conventions.d.ts +13 -2
- package/dist/types/conventions.d.ts.map +1 -1
- package/dist/types/core/Agent.d.ts +16 -1
- package/dist/types/core/Agent.d.ts.map +1 -1
- package/dist/types/core/agent/AgentBuilder.d.ts +99 -0
- package/dist/types/core/agent/AgentBuilder.d.ts.map +1 -1
- package/dist/types/core/agent/buildAgentChart.d.ts +8 -0
- package/dist/types/core/agent/buildAgentChart.d.ts.map +1 -1
- package/dist/types/core/agent/stages/callLLM.d.ts +4 -0
- package/dist/types/core/agent/stages/callLLM.d.ts.map +1 -1
- package/dist/types/core/agent/stages/prepareFinal.d.ts.map +1 -1
- package/dist/types/core/agent/stages/seed.d.ts.map +1 -1
- package/dist/types/core/agent/stages/toolCalls.d.ts.map +1 -1
- package/dist/types/core/agent/types.d.ts +12 -0
- package/dist/types/core/agent/types.d.ts.map +1 -1
- package/dist/types/core/slots/buildThinkingSubflow.d.ts +41 -0
- package/dist/types/core/slots/buildThinkingSubflow.d.ts.map +1 -0
- package/dist/types/events/payloads.d.ts +100 -0
- package/dist/types/events/payloads.d.ts.map +1 -1
- package/dist/types/events/registry.d.ts +7 -1
- package/dist/types/events/registry.d.ts.map +1 -1
- package/dist/types/recorders/observability/BoundaryRecorder.d.ts.map +1 -1
- package/dist/types/recorders/observability/FlowchartRecorder.d.ts +9 -0
- package/dist/types/recorders/observability/FlowchartRecorder.d.ts.map +1 -1
- package/dist/types/security/index.d.ts +1 -0
- package/dist/types/security/index.d.ts.map +1 -1
- package/dist/types/security/thinkingRedaction.d.ts +51 -0
- package/dist/types/security/thinkingRedaction.d.ts.map +1 -0
- package/dist/types/thinking/AnthropicThinkingHandler.d.ts +43 -0
- package/dist/types/thinking/AnthropicThinkingHandler.d.ts.map +1 -0
- package/dist/types/thinking/MockThinkingHandler.d.ts +51 -0
- package/dist/types/thinking/MockThinkingHandler.d.ts.map +1 -0
- package/dist/types/thinking/OpenAIThinkingHandler.d.ts +38 -0
- package/dist/types/thinking/OpenAIThinkingHandler.d.ts.map +1 -0
- package/dist/types/thinking/index.d.ts +52 -0
- package/dist/types/thinking/index.d.ts.map +1 -0
- package/dist/types/thinking/registry.d.ts +34 -0
- package/dist/types/thinking/registry.d.ts.map +1 -0
- package/dist/types/thinking/types.d.ts +163 -0
- package/dist/types/thinking/types.d.ts.map +1 -0
- package/package.json +6 -1
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* AnthropicThinkingHandler — normalizes Anthropic's extended-thinking
|
|
4
|
+
* response shape into the framework's `ThinkingBlock[]` contract.
|
|
5
|
+
*
|
|
6
|
+
* Anthropic emits thinking via blocks in `response.content`:
|
|
7
|
+
*
|
|
8
|
+
* ```ts
|
|
9
|
+
* { type: 'thinking', thinking: 'reasoning text', signature: 'opaque-base64' }
|
|
10
|
+
* { type: 'redacted_thinking', signature: 'opaque-base64' }
|
|
11
|
+
* { type: 'text', text: 'visible content' }
|
|
12
|
+
* { type: 'tool_use', id, name, input }
|
|
13
|
+
* ```
|
|
14
|
+
*
|
|
15
|
+
* The handler filters for `'thinking'` + `'redacted_thinking'` blocks,
|
|
16
|
+
* preserves the `signature` field BYTE-EXACT (Anthropic validates
|
|
17
|
+
* signatures server-side on the next turn — any modification = HTTP 400),
|
|
18
|
+
* and ignores other block types (visible text + tool calls flow through
|
|
19
|
+
* the existing `LLMResponse.content` / `LLMResponse.toolCalls` paths).
|
|
20
|
+
*
|
|
21
|
+
* **Critical invariant:** signature pass-through is byte-exact. The
|
|
22
|
+
* handler MUST NOT trim, normalize encoding, JSON-roundtrip, or
|
|
23
|
+
* otherwise touch the signature string. Tests verify this explicitly.
|
|
24
|
+
*
|
|
25
|
+
* **Three input shapes** Anthropic produces (per Phase 4a panel review):
|
|
26
|
+
* 1. Non-streaming response: full `response.content` array
|
|
27
|
+
* 2. Streaming aggregated: AnthropicProvider accumulates chunks +
|
|
28
|
+
* calls handler with the same array shape
|
|
29
|
+
* 3. Bedrock-via-Anthropic: deferred to Phase 5+ (separate handler
|
|
30
|
+
* or extension of this one)
|
|
31
|
+
*
|
|
32
|
+
* Streaming + non-streaming converge on shape #1 because the provider
|
|
33
|
+
* handles the distinction — handler only sees the assembled content
|
|
34
|
+
* array.
|
|
35
|
+
*
|
|
36
|
+
* **`parseChunk` is OPTIONAL** — Phase 3's framework path populates
|
|
37
|
+
* `LLMChunk.thinkingDelta` from inside AnthropicProvider's `stream()`
|
|
38
|
+
* directly, bypassing handler.parseChunk. We still implement it for
|
|
39
|
+
* consumer integrations that want to use the handler on raw Anthropic
|
|
40
|
+
* chunks directly (e.g., custom transports).
|
|
41
|
+
*/
|
|
42
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
43
|
+
exports.anthropicThinkingHandler = void 0;
|
|
44
|
+
function isAnthropicContentArray(raw) {
|
|
45
|
+
return Array.isArray(raw);
|
|
46
|
+
}
|
|
47
|
+
function isThinkingBlock(b) {
|
|
48
|
+
return b.type === 'thinking';
|
|
49
|
+
}
|
|
50
|
+
function isRedactedThinkingBlock(b) {
|
|
51
|
+
return b.type === 'redacted_thinking';
|
|
52
|
+
}
|
|
53
|
+
function isAnthropicChunk(chunk) {
|
|
54
|
+
return typeof chunk === 'object' && chunk !== null;
|
|
55
|
+
}
|
|
56
|
+
exports.anthropicThinkingHandler = {
|
|
57
|
+
id: 'anthropic',
|
|
58
|
+
// 'browser-anthropic' shares the same response shape (raw Anthropic
|
|
59
|
+
// wire format) — both providers route through fromAnthropicResponse
|
|
60
|
+
// which sets `rawThinking` to `message.content`. Bedrock Claude
|
|
61
|
+
// would also fit here but ships as a separate handler if/when its
|
|
62
|
+
// shape diverges.
|
|
63
|
+
providerNames: ['anthropic', 'browser-anthropic'],
|
|
64
|
+
normalize(raw) {
|
|
65
|
+
if (!isAnthropicContentArray(raw))
|
|
66
|
+
return [];
|
|
67
|
+
const out = [];
|
|
68
|
+
for (const block of raw) {
|
|
69
|
+
if (isThinkingBlock(block)) {
|
|
70
|
+
// Byte-exact signature preservation: pass through as-is.
|
|
71
|
+
// No String() coercion that could normalize encoding; if
|
|
72
|
+
// Anthropic ever emits a non-string signature it would be a
|
|
73
|
+
// wire-protocol violation we want to surface, not silently
|
|
74
|
+
// coerce.
|
|
75
|
+
out.push({
|
|
76
|
+
type: 'thinking',
|
|
77
|
+
// Don't touch content — pass through. Anthropic guarantees
|
|
78
|
+
// it's a string when the field is present.
|
|
79
|
+
content: block.thinking,
|
|
80
|
+
...(block.signature !== undefined && { signature: block.signature }),
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
else if (isRedactedThinkingBlock(block)) {
|
|
84
|
+
// Redacted blocks have no readable content but the signature
|
|
85
|
+
// is still REQUIRED for round-trip. Empty content is the
|
|
86
|
+
// contract (per Phase 1 ThinkingBlock JSDoc).
|
|
87
|
+
out.push({
|
|
88
|
+
type: 'redacted_thinking',
|
|
89
|
+
content: '',
|
|
90
|
+
...(block.signature !== undefined && { signature: block.signature }),
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
// Other block types (text, tool_use, etc.) flow through the
|
|
94
|
+
// existing LLMResponse paths — ignore here.
|
|
95
|
+
}
|
|
96
|
+
return out;
|
|
97
|
+
},
|
|
98
|
+
parseChunk(chunk) {
|
|
99
|
+
// Optional escape hatch — framework path doesn't call this
|
|
100
|
+
// (AnthropicProvider populates LLMChunk.thinkingDelta directly).
|
|
101
|
+
// Provided for consumer integrations using the handler on raw
|
|
102
|
+
// Anthropic chunks directly.
|
|
103
|
+
if (!isAnthropicChunk(chunk))
|
|
104
|
+
return {};
|
|
105
|
+
const delta = chunk.delta;
|
|
106
|
+
if (!delta)
|
|
107
|
+
return {};
|
|
108
|
+
if (delta.type === 'thinking_delta' && typeof delta.thinking === 'string') {
|
|
109
|
+
return { thinkingDelta: delta.thinking };
|
|
110
|
+
}
|
|
111
|
+
return {};
|
|
112
|
+
},
|
|
113
|
+
};
|
|
114
|
+
//# sourceMappingURL=AnthropicThinkingHandler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AnthropicThinkingHandler.js","sourceRoot":"","sources":["../../src/thinking/AnthropicThinkingHandler.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;;;AAuCH,SAAS,uBAAuB,CAAC,GAAY;IAC3C,OAAO,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;AAC5B,CAAC;AAED,SAAS,eAAe,CAAC,CAAwB;IAC/C,OAAO,CAAC,CAAC,IAAI,KAAK,UAAU,CAAC;AAC/B,CAAC;AAED,SAAS,uBAAuB,CAAC,CAAwB;IACvD,OAAO,CAAC,CAAC,IAAI,KAAK,mBAAmB,CAAC;AACxC,CAAC;AAED,SAAS,gBAAgB,CAAC,KAAc;IACtC,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,CAAC;AACrD,CAAC;AAEY,QAAA,wBAAwB,GAAoB;IACvD,EAAE,EAAE,WAAW;IACf,oEAAoE;IACpE,oEAAoE;IACpE,gEAAgE;IAChE,kEAAkE;IAClE,kBAAkB;IAClB,aAAa,EAAE,CAAC,WAAW,EAAE,mBAAmB,CAAC;IAEjD,SAAS,CAAC,GAAY;QACpB,IAAI,CAAC,uBAAuB,CAAC,GAAG,CAAC;YAAE,OAAO,EAAE,CAAC;QAE7C,MAAM,GAAG,GAAoB,EAAE,CAAC;QAChC,KAAK,MAAM,KAAK,IAAI,GAAG,EAAE,CAAC;YACxB,IAAI,eAAe,CAAC,KAAK,CAAC,EAAE,CAAC;gBAC3B,yDAAyD;gBACzD,yDAAyD;gBACzD,4DAA4D;gBAC5D,2DAA2D;gBAC3D,UAAU;gBACV,GAAG,CAAC,IAAI,CAAC;oBACP,IAAI,EAAE,UAAU;oBAChB,2DAA2D;oBAC3D,2CAA2C;oBAC3C,OAAO,EAAE,KAAK,CAAC,QAAQ;oBACvB,GAAG,CAAC,KAAK,CAAC,SAAS,KAAK,SAAS,IAAI,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,EAAE,CAAC;iBACrE,CAAC,CAAC;YACL,CAAC;iBAAM,IAAI,uBAAuB,CAAC,KAAK,CAAC,EAAE,CAAC;gBAC1C,6DAA6D;gBAC7D,yDAAyD;gBACzD,8CAA8C;gBAC9C,GAAG,CAAC,IAAI,CAAC;oBACP,IAAI,EAAE,mBAAmB;oBACzB,OAAO,EAAE,EAAE;oBACX,GAAG,CAAC,KAAK,CAAC,SAAS,KAAK,SAAS,IAAI,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,EAAE,CAAC;iBACrE,CAAC,CAAC;YACL,CAAC;YACD,4DAA4D;YAC5D,4CAA4C;QAC9C,CAAC;QACD,OAAO,GAAG,CAAC;IACb,CAAC;IAED,UAAU,CAAC,KAAc;QACvB,2DAA2D;QAC3D,iEAAiE;QACjE,8DAA8D;QAC9D,6BAA6B;QAC7B,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC;YAAE,OAAO,EAAE,CAAC;QACxC,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC;QAC1B,IAAI,CAAC,KAAK;YAAE,OAAO,EAAE,CAAC;QACtB,IAAI,KAAK,CAAC,IAAI,KAAK,gBAAgB,IAAI,OAAO,KAAK,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;YAC1E,OAAO,EAAE,aAAa,EAAE,KAAK,CAAC,QAAQ,EAAE,CAAC;QAC3C,CAAC;QACD,OAAO,EAAE,CAAC;IACZ,CAAC;CACF,CAAC"}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* MockThinkingHandler — canonical example for the v2.14 ThinkingHandler
|
|
4
|
+
* contract. Used by:
|
|
5
|
+
*
|
|
6
|
+
* 1. Tests — drives the shared contract test (every shipped handler
|
|
7
|
+
* MUST satisfy the same invariants this mock demonstrates).
|
|
8
|
+
* 2. Future provider authors — reference implementation showing how
|
|
9
|
+
* to handle BOTH Anthropic-shape inputs (signed blocks, possibly
|
|
10
|
+
* redacted) and OpenAI-shape inputs (multi-block summary). The
|
|
11
|
+
* pattern of "discriminate by shape, normalize each branch" is
|
|
12
|
+
* reusable across providers.
|
|
13
|
+
* 3. The MockProvider for end-to-end tests of the framework wiring
|
|
14
|
+
* without depending on a real LLM SDK.
|
|
15
|
+
*
|
|
16
|
+
* Defaults are deliberately sensitive-data-free — no fake PII, no
|
|
17
|
+
* fake-signature material that could be confused for real cryptography,
|
|
18
|
+
* no internal-looking IDs. Sets the example for consumer-authored
|
|
19
|
+
* handlers.
|
|
20
|
+
*/
|
|
21
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
22
|
+
exports.mockThinkingHandler = exports.mockOpenAIRaw = exports.mockAnthropicRaw = void 0;
|
|
23
|
+
function isMockRaw(raw) {
|
|
24
|
+
if (typeof raw !== 'object' || raw === null)
|
|
25
|
+
return false;
|
|
26
|
+
const r = raw;
|
|
27
|
+
// Accept only well-formed shapes — protects against {kind: 'anthropic'}
|
|
28
|
+
// missing blocks (would crash .map). The framework's failure-isolation
|
|
29
|
+
// would catch the throw, but defending here keeps the contract
|
|
30
|
+
// "normalize never throws on garbage" tighter.
|
|
31
|
+
if (r.kind === 'anthropic')
|
|
32
|
+
return Array.isArray(r.blocks);
|
|
33
|
+
if (r.kind === 'openai')
|
|
34
|
+
return Array.isArray(r.summarySteps);
|
|
35
|
+
return false;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Build an Anthropic-style raw input for tests. Signature is a marker
|
|
39
|
+
* string — real Anthropic signatures are opaque base64.
|
|
40
|
+
*/
|
|
41
|
+
function mockAnthropicRaw(blocks) {
|
|
42
|
+
return {
|
|
43
|
+
kind: 'anthropic',
|
|
44
|
+
blocks: blocks.map((b) => ({
|
|
45
|
+
type: b.redacted ? 'redacted_thinking' : 'thinking',
|
|
46
|
+
...(b.redacted ? {} : { thinking: b.content }),
|
|
47
|
+
...(b.signature !== undefined && { signature: b.signature }),
|
|
48
|
+
})),
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
exports.mockAnthropicRaw = mockAnthropicRaw;
|
|
52
|
+
/**
|
|
53
|
+
* Build an OpenAI-style raw input for tests — one summary step per
|
|
54
|
+
* string. Each step becomes a separate ThinkingBlock with `summary: true`.
|
|
55
|
+
*/
|
|
56
|
+
function mockOpenAIRaw(summarySteps) {
|
|
57
|
+
return { kind: 'openai', summarySteps };
|
|
58
|
+
}
|
|
59
|
+
exports.mockOpenAIRaw = mockOpenAIRaw;
|
|
60
|
+
exports.mockThinkingHandler = {
|
|
61
|
+
id: 'mock',
|
|
62
|
+
// Matches the MockProvider's name; framework auto-wires when
|
|
63
|
+
// Agent uses MockProvider in tests.
|
|
64
|
+
providerNames: ['mock'],
|
|
65
|
+
normalize(raw) {
|
|
66
|
+
if (!isMockRaw(raw))
|
|
67
|
+
return [];
|
|
68
|
+
if (raw.kind === 'anthropic') {
|
|
69
|
+
return raw.blocks.map((b) => {
|
|
70
|
+
if (b.type === 'redacted_thinking') {
|
|
71
|
+
return {
|
|
72
|
+
type: 'redacted_thinking',
|
|
73
|
+
content: '',
|
|
74
|
+
...(b.signature !== undefined && { signature: b.signature }),
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
return {
|
|
78
|
+
type: 'thinking',
|
|
79
|
+
content: b.thinking ?? '',
|
|
80
|
+
...(b.signature !== undefined && { signature: b.signature }),
|
|
81
|
+
};
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
// OpenAI-style: one block per summary step, all marked summary: true.
|
|
85
|
+
return raw.summarySteps.map((content) => ({
|
|
86
|
+
type: 'thinking',
|
|
87
|
+
content,
|
|
88
|
+
summary: true,
|
|
89
|
+
}));
|
|
90
|
+
},
|
|
91
|
+
parseChunk(chunk) {
|
|
92
|
+
// Mock streams thinking via { thinkingDelta: '...' } shape.
|
|
93
|
+
if (typeof chunk !== 'object' || chunk === null)
|
|
94
|
+
return {};
|
|
95
|
+
const c = chunk;
|
|
96
|
+
return typeof c.thinkingDelta === 'string' ? { thinkingDelta: c.thinkingDelta } : {};
|
|
97
|
+
},
|
|
98
|
+
};
|
|
99
|
+
//# sourceMappingURL=MockThinkingHandler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MockThinkingHandler.js","sourceRoot":"","sources":["../../src/thinking/MockThinkingHandler.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* OpenAIThinkingHandler — normalizes OpenAI's o1/o3 reasoning_summary
|
|
4
|
+
* structured output into the framework's `ThinkingBlock[]` contract.
|
|
5
|
+
*
|
|
6
|
+
* OpenAI's reasoning_summary shape varies by model + API version:
|
|
7
|
+
*
|
|
8
|
+
* 1. Older o1 format — simple string:
|
|
9
|
+
* "I worked through the problem by first..."
|
|
10
|
+
*
|
|
11
|
+
* 2. Newer o3+ structured — array of summary items:
|
|
12
|
+
* [
|
|
13
|
+
* { type: 'summary_text', text: 'Identify the user request' },
|
|
14
|
+
* { type: 'summary_text', text: 'Choose appropriate tool' },
|
|
15
|
+
* ]
|
|
16
|
+
*
|
|
17
|
+
* 3. Missing entirely — most calls (gpt-4o, or o1/o3 without
|
|
18
|
+
* reasoning_summary param requested) → undefined raw input
|
|
19
|
+
*
|
|
20
|
+
* Handler dispatches on shape; output is `ThinkingBlock[]` with
|
|
21
|
+
* `summary: true` per Phase 1 contract — distinguishes structured-
|
|
22
|
+
* summary blocks from raw thinking content (Anthropic's shape).
|
|
23
|
+
*
|
|
24
|
+
* **No signature** — OpenAI doesn't sign reasoning. The output's
|
|
25
|
+
* `signature` field stays undefined. No round-trip integrity invariant
|
|
26
|
+
* (unlike Anthropic).
|
|
27
|
+
*
|
|
28
|
+
* **No `parseChunk`** — OpenAI doesn't stream reasoning content as of
|
|
29
|
+
* early 2026. Reasoning arrives only on the terminal response. Per
|
|
30
|
+
* Phase 1 design, `parseChunk` is optional; we omit entirely.
|
|
31
|
+
*
|
|
32
|
+
* **No `usage.thinking` computation** — reasoning_tokens lives on
|
|
33
|
+
* `response.usage.completion_tokens_details.reasoning_tokens` and is
|
|
34
|
+
* the OpenAIProvider's job to surface (deferred). Handler doesn't
|
|
35
|
+
* compute token counts.
|
|
36
|
+
*/
|
|
37
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
38
|
+
exports.openAIThinkingHandler = void 0;
|
|
39
|
+
function isOpenAIStructuredArray(raw) {
|
|
40
|
+
return Array.isArray(raw);
|
|
41
|
+
}
|
|
42
|
+
exports.openAIThinkingHandler = {
|
|
43
|
+
id: 'openai',
|
|
44
|
+
providerNames: ['openai'],
|
|
45
|
+
normalize(raw) {
|
|
46
|
+
if (raw === undefined || raw === null)
|
|
47
|
+
return [];
|
|
48
|
+
// Shape 1: simple string (older o1 format).
|
|
49
|
+
if (typeof raw === 'string') {
|
|
50
|
+
return raw.length > 0 ? [{ type: 'thinking', content: raw, summary: true }] : [];
|
|
51
|
+
}
|
|
52
|
+
// Shape 2: structured array of summary items (newer o3+ format).
|
|
53
|
+
if (isOpenAIStructuredArray(raw)) {
|
|
54
|
+
const out = [];
|
|
55
|
+
for (const item of raw) {
|
|
56
|
+
// Tolerate items missing `text` (defensive — wire format may
|
|
57
|
+
// evolve). Skip entries without usable content.
|
|
58
|
+
if (typeof item.text === 'string' && item.text.length > 0) {
|
|
59
|
+
out.push({
|
|
60
|
+
type: 'thinking',
|
|
61
|
+
content: item.text,
|
|
62
|
+
summary: true,
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
return out;
|
|
67
|
+
}
|
|
68
|
+
// Unknown shape — return empty rather than throw. The framework
|
|
69
|
+
// catches throws and emits parse_failed; here we choose graceful
|
|
70
|
+
// empty for unknown OpenAI evolutions (forward-compat).
|
|
71
|
+
return [];
|
|
72
|
+
},
|
|
73
|
+
// No parseChunk — OpenAI doesn't stream reasoning content.
|
|
74
|
+
};
|
|
75
|
+
//# sourceMappingURL=OpenAIThinkingHandler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"OpenAIThinkingHandler.js","sourceRoot":"","sources":["../../src/thinking/OpenAIThinkingHandler.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;;;AAYH,SAAS,uBAAuB,CAAC,GAAY;IAC3C,OAAO,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;AAC5B,CAAC;AAEY,QAAA,qBAAqB,GAAoB;IACpD,EAAE,EAAE,QAAQ;IACZ,aAAa,EAAE,CAAC,QAAQ,CAAC;IAEzB,SAAS,CAAC,GAAY;QACpB,IAAI,GAAG,KAAK,SAAS,IAAI,GAAG,KAAK,IAAI;YAAE,OAAO,EAAE,CAAC;QAEjD,4CAA4C;QAC5C,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;YAC5B,OAAO,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QACnF,CAAC;QAED,iEAAiE;QACjE,IAAI,uBAAuB,CAAC,GAAG,CAAC,EAAE,CAAC;YACjC,MAAM,GAAG,GAAoB,EAAE,CAAC;YAChC,KAAK,MAAM,IAAI,IAAI,GAAG,EAAE,CAAC;gBACvB,6DAA6D;gBAC7D,gDAAgD;gBAChD,IAAI,OAAO,IAAI,CAAC,IAAI,KAAK,QAAQ,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBAC1D,GAAG,CAAC,IAAI,CAAC;wBACP,IAAI,EAAE,UAAU;wBAChB,OAAO,EAAE,IAAI,CAAC,IAAI;wBAClB,OAAO,EAAE,IAAI;qBACd,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;YACD,OAAO,GAAG,CAAC;QACb,CAAC;QAED,gEAAgE;QAChE,iEAAiE;QACjE,wDAAwD;QACxD,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,2DAA2D;CAC5D,CAAC"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* agentfootprint/thinking — extended-thinking subsystem (v2.14+).
|
|
4
|
+
*
|
|
5
|
+
* **Two-layer architecture:**
|
|
6
|
+
*
|
|
7
|
+
* • CONSUMER-FACING: `ThinkingHandler` — simple function-pair
|
|
8
|
+
* implemented by provider authors.
|
|
9
|
+
* • FRAMEWORK-INTERNAL: each handler is auto-wrapped in a real
|
|
10
|
+
* footprintjs subflow at chart build time;
|
|
11
|
+
* shows in trace as own runtimeStageId.
|
|
12
|
+
*
|
|
13
|
+
* **Auto-wire by provider name:**
|
|
14
|
+
*
|
|
15
|
+
* ```ts
|
|
16
|
+
* import { Agent } from 'agentfootprint';
|
|
17
|
+
*
|
|
18
|
+
* // Library scans SHIPPED_THINKING_HANDLERS, finds the handler
|
|
19
|
+
* // whose providerNames includes provider.name. Mounted as a
|
|
20
|
+
* // sub-subflow of sf-call-llm.
|
|
21
|
+
* const agent = Agent.create({ provider: anthropic({...}), model: '...' })
|
|
22
|
+
* .build();
|
|
23
|
+
*
|
|
24
|
+
* // Opt out:
|
|
25
|
+
* // .thinkingHandler(undefined)
|
|
26
|
+
* // Override with a custom handler:
|
|
27
|
+
* // .thinkingHandler(myCustomHandler)
|
|
28
|
+
* ```
|
|
29
|
+
*
|
|
30
|
+
* **Custom handlers:**
|
|
31
|
+
*
|
|
32
|
+
* ```ts
|
|
33
|
+
* import { type ThinkingHandler } from 'agentfootprint/thinking';
|
|
34
|
+
*
|
|
35
|
+
* export const geminiThinkingHandler: ThinkingHandler = {
|
|
36
|
+
* id: 'gemini',
|
|
37
|
+
* providerNames: ['gemini'],
|
|
38
|
+
* normalize(raw) { ... },
|
|
39
|
+
* parseChunk(chunk) { ... }, // optional
|
|
40
|
+
* };
|
|
41
|
+
* ```
|
|
42
|
+
*
|
|
43
|
+
* Failure isolation: handler `normalize()` throws are caught by the
|
|
44
|
+
* framework — emit `agentfootprint.agent.thinking_parse_failed`, drop
|
|
45
|
+
* the blocks, continue. Same graceful pattern as v2.11.6
|
|
46
|
+
* `tools.discovery_failed`.
|
|
47
|
+
*/
|
|
48
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
49
|
+
exports.findThinkingHandler = exports.SHIPPED_THINKING_HANDLERS = exports.openAIThinkingHandler = exports.anthropicThinkingHandler = exports.mockOpenAIRaw = exports.mockAnthropicRaw = exports.mockThinkingHandler = void 0;
|
|
50
|
+
var MockThinkingHandler_js_1 = require("./MockThinkingHandler.js");
|
|
51
|
+
Object.defineProperty(exports, "mockThinkingHandler", { enumerable: true, get: function () { return MockThinkingHandler_js_1.mockThinkingHandler; } });
|
|
52
|
+
Object.defineProperty(exports, "mockAnthropicRaw", { enumerable: true, get: function () { return MockThinkingHandler_js_1.mockAnthropicRaw; } });
|
|
53
|
+
Object.defineProperty(exports, "mockOpenAIRaw", { enumerable: true, get: function () { return MockThinkingHandler_js_1.mockOpenAIRaw; } });
|
|
54
|
+
var AnthropicThinkingHandler_js_1 = require("./AnthropicThinkingHandler.js");
|
|
55
|
+
Object.defineProperty(exports, "anthropicThinkingHandler", { enumerable: true, get: function () { return AnthropicThinkingHandler_js_1.anthropicThinkingHandler; } });
|
|
56
|
+
var OpenAIThinkingHandler_js_1 = require("./OpenAIThinkingHandler.js");
|
|
57
|
+
Object.defineProperty(exports, "openAIThinkingHandler", { enumerable: true, get: function () { return OpenAIThinkingHandler_js_1.openAIThinkingHandler; } });
|
|
58
|
+
var registry_js_1 = require("./registry.js");
|
|
59
|
+
Object.defineProperty(exports, "SHIPPED_THINKING_HANDLERS", { enumerable: true, get: function () { return registry_js_1.SHIPPED_THINKING_HANDLERS; } });
|
|
60
|
+
Object.defineProperty(exports, "findThinkingHandler", { enumerable: true, get: function () { return registry_js_1.findThinkingHandler; } });
|
|
61
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/thinking/index.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6CG;;;AAIH,mEAAgG;AAAvF,6HAAA,mBAAmB,OAAA;AAAE,0HAAA,gBAAgB,OAAA;AAAE,uHAAA,aAAa,OAAA;AAE7D,6EAAyE;AAAhE,uIAAA,wBAAwB,OAAA;AAEjC,uEAAmE;AAA1D,iIAAA,qBAAqB,OAAA;AAE9B,6CAA+E;AAAtE,wHAAA,yBAAyB,OAAA;AAAE,kHAAA,mBAAmB,OAAA"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Registry — single source of truth for the framework's auto-wire
|
|
4
|
+
* logic AND the shared contract test.
|
|
5
|
+
*
|
|
6
|
+
* Phase 3 wiring scans this array at chart build time and selects the
|
|
7
|
+
* first handler whose `providerNames` includes the active
|
|
8
|
+
* `provider.name`. Phase 4a adds AnthropicThinkingHandler; Phase 5
|
|
9
|
+
* adds OpenAIThinkingHandler — append-only as new providers ship.
|
|
10
|
+
*
|
|
11
|
+
* Future provider authors:
|
|
12
|
+
* • Implement `ThinkingHandler` for your provider
|
|
13
|
+
* • Append to this array
|
|
14
|
+
* • The shared contract test in `test/thinking/contract.test.ts`
|
|
15
|
+
* verifies your handler honors the framework's invariants
|
|
16
|
+
*/
|
|
17
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
+
exports.findThinkingHandler = exports.SHIPPED_THINKING_HANDLERS = void 0;
|
|
19
|
+
const AnthropicThinkingHandler_js_1 = require("./AnthropicThinkingHandler.js");
|
|
20
|
+
const MockThinkingHandler_js_1 = require("./MockThinkingHandler.js");
|
|
21
|
+
const OpenAIThinkingHandler_js_1 = require("./OpenAIThinkingHandler.js");
|
|
22
|
+
/**
|
|
23
|
+
* All thinking handlers shipped with the library. Append in alphabetical
|
|
24
|
+
* order (by `id`) so diffs stay readable as new handlers land.
|
|
25
|
+
*/
|
|
26
|
+
exports.SHIPPED_THINKING_HANDLERS = [
|
|
27
|
+
AnthropicThinkingHandler_js_1.anthropicThinkingHandler,
|
|
28
|
+
MockThinkingHandler_js_1.mockThinkingHandler,
|
|
29
|
+
OpenAIThinkingHandler_js_1.openAIThinkingHandler,
|
|
30
|
+
];
|
|
31
|
+
/**
|
|
32
|
+
* Look up a handler by `provider.name`. Returns the first match in
|
|
33
|
+
* `SHIPPED_THINKING_HANDLERS`. Returns `undefined` when no handler
|
|
34
|
+
* matches — framework treats this as "no thinking support for this
|
|
35
|
+
* provider", which is the correct default for providers that don't
|
|
36
|
+
* emit thinking content (gpt-3.5, mistral, etc.).
|
|
37
|
+
*
|
|
38
|
+
* Used by:
|
|
39
|
+
* • Phase 3 framework auto-wire (chart build time)
|
|
40
|
+
* • Tests verifying registry lookup
|
|
41
|
+
*/
|
|
42
|
+
function findThinkingHandler(providerName) {
|
|
43
|
+
for (const handler of exports.SHIPPED_THINKING_HANDLERS) {
|
|
44
|
+
if (handler.providerNames.includes(providerName))
|
|
45
|
+
return handler;
|
|
46
|
+
}
|
|
47
|
+
return undefined;
|
|
48
|
+
}
|
|
49
|
+
exports.findThinkingHandler = findThinkingHandler;
|
|
50
|
+
//# sourceMappingURL=registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/thinking/registry.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;GAcG;;;AAEH,+EAAyE;AACzE,qEAA+D;AAC/D,yEAAmE;AAGnE;;;GAGG;AACU,QAAA,yBAAyB,GAA+B;IACnE,sDAAwB;IACxB,4CAAmB;IACnB,gDAAqB;CACtB,CAAC;AAEF;;;;;;;;;;GAUG;AACH,SAAgB,mBAAmB,CAAC,YAAoB;IACtD,KAAK,MAAM,OAAO,IAAI,iCAAyB,EAAE,CAAC;QAChD,IAAI,OAAO,CAAC,aAAa,CAAC,QAAQ,CAAC,YAAY,CAAC;YAAE,OAAO,OAAO,CAAC;IACnE,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AALD,kDAKC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Thinking — public types for the v2.14 extended-thinking subsystem.
|
|
4
|
+
*
|
|
5
|
+
* Mental model — TWO-LAYER architecture:
|
|
6
|
+
*
|
|
7
|
+
* • CONSUMER-FACING: `ThinkingHandler` — a simple function-pair
|
|
8
|
+
* (id, providerNames, normalize, parseChunk?).
|
|
9
|
+
* Provider authors and custom-LLM consumers
|
|
10
|
+
* implement THIS shape.
|
|
11
|
+
*
|
|
12
|
+
* • FRAMEWORK-INTERNAL: each `ThinkingHandler` is auto-wrapped in a
|
|
13
|
+
* real footprintjs subflow at chart build time.
|
|
14
|
+
* The subflow gets its own `runtimeStageId`,
|
|
15
|
+
* narrative entry, and InOutRecorder boundary
|
|
16
|
+
* — full trace observability for free without
|
|
17
|
+
* the consumer writing flowchart code.
|
|
18
|
+
*
|
|
19
|
+
* Same pattern as how consumers write a `Tool` and the framework wraps
|
|
20
|
+
* dispatch in a tool-call subflow, or how consumers write a
|
|
21
|
+
* `ToolProvider` and the framework wraps `list()` in the Tools slot
|
|
22
|
+
* subflow.
|
|
23
|
+
*
|
|
24
|
+
* @see SHIPPED_THINKING_HANDLERS for the registry the framework uses
|
|
25
|
+
* to auto-wire by `provider.name` (Phase 3 wiring).
|
|
26
|
+
* @see MockThinkingHandler for the canonical example demonstrating
|
|
27
|
+
* both Anthropic-shape (signed blocks) and OpenAI-shape (multi-
|
|
28
|
+
* block summary) inputs.
|
|
29
|
+
*/
|
|
30
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
31
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/thinking/types.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG"}
|
|
@@ -31,6 +31,10 @@ interface AnthropicCreateParams {
|
|
|
31
31
|
tools?: AnthropicTool[];
|
|
32
32
|
temperature?: number;
|
|
33
33
|
stop_sequences?: string[];
|
|
34
|
+
thinking?: {
|
|
35
|
+
type: 'enabled';
|
|
36
|
+
budget_tokens: number;
|
|
37
|
+
};
|
|
34
38
|
}
|
|
35
39
|
interface AnthropicMessageParam {
|
|
36
40
|
role: 'user' | 'assistant';
|
|
@@ -49,6 +53,13 @@ type AnthropicContentBlock = {
|
|
|
49
53
|
tool_use_id: string;
|
|
50
54
|
content: string;
|
|
51
55
|
is_error?: boolean;
|
|
56
|
+
} | {
|
|
57
|
+
type: 'thinking';
|
|
58
|
+
thinking: string;
|
|
59
|
+
signature?: string;
|
|
60
|
+
} | {
|
|
61
|
+
type: 'redacted_thinking';
|
|
62
|
+
signature?: string;
|
|
52
63
|
};
|
|
53
64
|
interface AnthropicTool {
|
|
54
65
|
name: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AnthropicProvider.d.ts","sourceRoot":"","sources":["../../../../src/adapters/llm/AnthropicProvider.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,KAAK,EACV,QAAQ,EAER,WAAW,EACX,UAAU,EACV,WAAW,EAEZ,MAAM,aAAa,CAAC;AAKrB,UAAU,eAAe;IACvB,QAAQ,EAAE;QACR,MAAM,CAAC,MAAM,EAAE,qBAAqB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC;QACjE,MAAM,CAAC,MAAM,EAAE,qBAAqB,GAAG,eAAe,CAAC;KACxD,CAAC;CACH;AAED,UAAU,qBAAqB;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,qBAAqB,EAAE,CAAC;IAClC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,aAAa,EAAE,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"AnthropicProvider.d.ts","sourceRoot":"","sources":["../../../../src/adapters/llm/AnthropicProvider.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BrowserAnthropicProvider.d.ts","sourceRoot":"","sources":["../../../../src/adapters/llm/BrowserAnthropicProvider.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,KAAK,EACV,QAAQ,EAER,WAAW,EACX,UAAU,EACV,WAAW,EAEZ,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"BrowserAnthropicProvider.d.ts","sourceRoot":"","sources":["../../../../src/adapters/llm/BrowserAnthropicProvider.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,KAAK,EACV,QAAQ,EAER,WAAW,EACX,UAAU,EACV,WAAW,EAEZ,MAAM,aAAa,CAAC;AAsDrB,MAAM,WAAW,+BAA+B;IAC9C,iEAAiE;IACjE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,8DAA8D;IAC9D,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B,wCAAwC;IACxC,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IACnC,+DAA+D;IAC/D,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,iEAAiE;IACjE,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,KAAK,CAAC;CAChC;AAED,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,+BAA+B,GAAG,WAAW,CAsPtF;AAED,qBAAa,wBAAyB,YAAW,WAAW;IAC1D,QAAQ,CAAC,IAAI,uBAAuB;IACpC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAc;gBAExB,OAAO,EAAE,+BAA+B;IAIpD,QAAQ,CAAC,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC;IAI/C,MAAM,CAAC,GAAG,EAAE,UAAU,GAAG,aAAa,CAAC,QAAQ,CAAC;CAIjD"}
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
* these interfaces — never on concrete adapters.
|
|
14
14
|
*/
|
|
15
15
|
import type { ContextRole, ContextSlot, ContextSource } from '../events/types.js';
|
|
16
|
+
import type { ThinkingBlock } from '../thinking/types.js';
|
|
16
17
|
export interface LLMMessage {
|
|
17
18
|
readonly role: ContextRole;
|
|
18
19
|
readonly content: string;
|
|
@@ -33,6 +34,26 @@ export interface LLMMessage {
|
|
|
33
34
|
readonly name: string;
|
|
34
35
|
readonly args: Readonly<Record<string, unknown>>;
|
|
35
36
|
}[];
|
|
37
|
+
/**
|
|
38
|
+
* v2.14 — Thinking blocks emitted by the LLM on assistant turns.
|
|
39
|
+
*
|
|
40
|
+
* Required for Anthropic extended-thinking + tool-use flows: signed
|
|
41
|
+
* blocks MUST be echoed BYTE-EXACT in subsequent assistant turns or
|
|
42
|
+
* Anthropic's API rejects with 400. The framework persists blocks
|
|
43
|
+
* here so the AnthropicProvider's serializer (Phase 4b) can restore
|
|
44
|
+
* them on the next request.
|
|
45
|
+
*
|
|
46
|
+
* **Persistence model — DIFFERENT from `ephemeral`:**
|
|
47
|
+
* - `ephemeral` messages: NOT persisted to scope.history
|
|
48
|
+
* - `thinkingBlocks`: PERSISTED (required for signature round-trip)
|
|
49
|
+
*
|
|
50
|
+
* Visible to recorders + audit by default. Use
|
|
51
|
+
* `RedactionPolicy.thinkingPatterns` (Phase 3) to scrub sensitive
|
|
52
|
+
* reasoning content before audit-log adapters fire.
|
|
53
|
+
*
|
|
54
|
+
* Empty array OR undefined when no thinking is present (most calls).
|
|
55
|
+
*/
|
|
56
|
+
readonly thinkingBlocks?: readonly ThinkingBlock[];
|
|
36
57
|
/**
|
|
37
58
|
* v2.13 — PERSISTENCE flag (NOT a visibility flag). When `true`:
|
|
38
59
|
* • The message IS sent to the LLM as part of the next request
|
|
@@ -83,6 +104,32 @@ export interface LLMRequest {
|
|
|
83
104
|
* cache support (OpenAI auto-cache, Mock, NoOp) ignore it.
|
|
84
105
|
*/
|
|
85
106
|
readonly cacheMarkers?: readonly import('../cache/types.js').CacheMarker[];
|
|
107
|
+
/**
|
|
108
|
+
* v2.14 — request the LLM emit reasoning/thinking content on this call.
|
|
109
|
+
*
|
|
110
|
+
* Activation: presence of this field tells the provider to ASK for
|
|
111
|
+
* thinking. Anthropic translates to `thinking: { type: 'enabled',
|
|
112
|
+
* budget_tokens: budget }` on the wire. OpenAI ignores (o1/o3
|
|
113
|
+
* thinking is selected at the model id level, not per-request).
|
|
114
|
+
*
|
|
115
|
+
* `budget` is the maximum reasoning tokens the model may spend.
|
|
116
|
+
* Anthropic requires it; recommended range 1024-32000 for
|
|
117
|
+
* claude-sonnet-4-5 / opus-4-5. Models that don't support extended
|
|
118
|
+
* thinking will reject the request with HTTP 400 — pick a supported
|
|
119
|
+
* model when setting this field.
|
|
120
|
+
*
|
|
121
|
+
* Independent from `LLMMessage.thinkingBlocks` (the response side):
|
|
122
|
+
* - `request.thinking` = activation (consumer ASKS for thinking)
|
|
123
|
+
* - `message.thinkingBlocks` = round-trip (consumer ECHOES prior
|
|
124
|
+
* assistant turn's signed blocks back to the model)
|
|
125
|
+
*
|
|
126
|
+
* Set via `AgentBuilder.thinking({ budget })` — applied to every
|
|
127
|
+
* LLM call the agent makes. Leave undefined to call without thinking
|
|
128
|
+
* (the v2.13 default).
|
|
129
|
+
*/
|
|
130
|
+
readonly thinking?: {
|
|
131
|
+
readonly budget: number;
|
|
132
|
+
};
|
|
86
133
|
}
|
|
87
134
|
export interface LLMResponse {
|
|
88
135
|
readonly content: string;
|
|
@@ -96,9 +143,43 @@ export interface LLMResponse {
|
|
|
96
143
|
readonly output: number;
|
|
97
144
|
readonly cacheRead?: number;
|
|
98
145
|
readonly cacheWrite?: number;
|
|
146
|
+
/**
|
|
147
|
+
* v2.14 — count of reasoning/thinking tokens used by the model.
|
|
148
|
+
* Distinct from `output` (which is visible-content tokens).
|
|
149
|
+
*
|
|
150
|
+
* Semantics:
|
|
151
|
+
* - `undefined` — provider doesn't expose / no thinking enabled
|
|
152
|
+
* on this call / call without extended thinking
|
|
153
|
+
* - `0` — thinking enabled but model produced no
|
|
154
|
+
* thinking tokens this call
|
|
155
|
+
* - `>0` — actual reasoning token count (billing-relevant
|
|
156
|
+
* for both Anthropic extended thinking and
|
|
157
|
+
* OpenAI o1/o3 reasoning_tokens)
|
|
158
|
+
*
|
|
159
|
+
* Cost dashboards reading `cost.tick` events should track this
|
|
160
|
+
* separately from `output` — pricing differs (Anthropic charges
|
|
161
|
+
* extended thinking at output rates; OpenAI o1/o3 reasoning tokens
|
|
162
|
+
* are billed as a separate line item).
|
|
163
|
+
*/
|
|
164
|
+
readonly thinking?: number;
|
|
99
165
|
};
|
|
100
166
|
readonly stopReason: string;
|
|
101
167
|
readonly providerRef?: string;
|
|
168
|
+
/**
|
|
169
|
+
* v2.14 — Provider-specific raw thinking data, opaque to the
|
|
170
|
+
* framework. Providers that support extended thinking populate this
|
|
171
|
+
* with their native shape (Anthropic: array of `{type, thinking,
|
|
172
|
+
* signature}` blocks; OpenAI: `reasoning_summary` value; custom:
|
|
173
|
+
* whatever the provider emits). The framework hands this to a
|
|
174
|
+
* configured `ThinkingHandler.normalize(rawThinking)` to produce
|
|
175
|
+
* the normalized `ThinkingBlock[]` that lands on
|
|
176
|
+
* `LLMMessage.thinkingBlocks`.
|
|
177
|
+
*
|
|
178
|
+
* Undefined when the provider has no thinking content for this call
|
|
179
|
+
* — most calls (gpt-4o, claude without extended thinking enabled,
|
|
180
|
+
* etc.). The thinking subflow's stage early-returns in this case.
|
|
181
|
+
*/
|
|
182
|
+
readonly rawThinking?: unknown;
|
|
102
183
|
}
|
|
103
184
|
export interface LLMChunk {
|
|
104
185
|
readonly tokenIndex: number;
|
|
@@ -119,6 +200,22 @@ export interface LLMChunk {
|
|
|
119
200
|
* authoritative payload in that case.
|
|
120
201
|
*/
|
|
121
202
|
readonly response?: LLMResponse;
|
|
203
|
+
/**
|
|
204
|
+
* v2.14 — streaming thinking-content tokens. Parallel to `content`
|
|
205
|
+
* but for the model's reasoning chain rather than visible output.
|
|
206
|
+
* Set on chunks that carry thinking deltas (Anthropic emits these
|
|
207
|
+
* via `content_block_delta` events with `delta.type === 'thinking_delta'`);
|
|
208
|
+
* undefined or empty on chunks that carry only visible-content tokens.
|
|
209
|
+
*
|
|
210
|
+
* Frameworks: this field drives `agentfootprint.stream.thinking_delta`
|
|
211
|
+
* events when a `ThinkingHandler.parseChunk()` returns one. Consumers
|
|
212
|
+
* who want to render thinking-as-it-streams subscribe to that event.
|
|
213
|
+
*
|
|
214
|
+
* Default consumer behavior: thinking tokens are NOT shown to end
|
|
215
|
+
* users via `enable.thinking({ stream: false })` (the default).
|
|
216
|
+
* Consumers explicitly opt in with `enable.thinking({ stream: true })`.
|
|
217
|
+
*/
|
|
218
|
+
readonly thinkingDelta?: string;
|
|
122
219
|
}
|
|
123
220
|
export interface LLMProvider {
|
|
124
221
|
readonly name: string;
|