@defai.digital/discussion-domain 13.0.3 → 13.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/budget-manager.d.ts +79 -0
- package/dist/budget-manager.d.ts.map +1 -0
- package/dist/budget-manager.js +155 -0
- package/dist/budget-manager.js.map +1 -0
- package/dist/confidence-extractor.d.ts +60 -0
- package/dist/confidence-extractor.d.ts.map +1 -0
- package/dist/confidence-extractor.js +251 -0
- package/dist/confidence-extractor.js.map +1 -0
- package/dist/consensus/synthesis.d.ts.map +1 -1
- package/dist/consensus/synthesis.js +2 -0
- package/dist/consensus/synthesis.js.map +1 -1
- package/dist/consensus/voting.d.ts +3 -0
- package/dist/consensus/voting.d.ts.map +1 -1
- package/dist/consensus/voting.js +15 -4
- package/dist/consensus/voting.js.map +1 -1
- package/dist/context-tracker.d.ts +77 -0
- package/dist/context-tracker.d.ts.map +1 -0
- package/dist/context-tracker.js +177 -0
- package/dist/context-tracker.js.map +1 -0
- package/dist/cost-tracker.d.ts +123 -0
- package/dist/cost-tracker.d.ts.map +1 -0
- package/dist/cost-tracker.js +196 -0
- package/dist/cost-tracker.js.map +1 -0
- package/dist/executor.d.ts.map +1 -1
- package/dist/executor.js +9 -0
- package/dist/executor.js.map +1 -1
- package/dist/index.d.ts +7 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +12 -0
- package/dist/index.js.map +1 -1
- package/dist/participant-resolver.d.ts +111 -0
- package/dist/participant-resolver.d.ts.map +1 -0
- package/dist/participant-resolver.js +160 -0
- package/dist/participant-resolver.js.map +1 -0
- package/dist/patterns/round-robin.d.ts +3 -0
- package/dist/patterns/round-robin.d.ts.map +1 -1
- package/dist/patterns/round-robin.js +41 -2
- package/dist/patterns/round-robin.js.map +1 -1
- package/dist/patterns/synthesis.d.ts +3 -0
- package/dist/patterns/synthesis.d.ts.map +1 -1
- package/dist/patterns/synthesis.js +77 -3
- package/dist/patterns/synthesis.js.map +1 -1
- package/dist/prompts/templates.d.ts +1 -0
- package/dist/prompts/templates.d.ts.map +1 -1
- package/dist/prompts/templates.js +3 -1
- package/dist/prompts/templates.js.map +1 -1
- package/dist/provider-bridge.d.ts +3 -1
- package/dist/provider-bridge.d.ts.map +1 -1
- package/dist/provider-bridge.js +48 -32
- package/dist/provider-bridge.js.map +1 -1
- package/dist/recursive-executor.d.ts +80 -0
- package/dist/recursive-executor.d.ts.map +1 -0
- package/dist/recursive-executor.js +354 -0
- package/dist/recursive-executor.js.map +1 -0
- package/dist/types.d.ts +83 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/package.json +2 -2
- package/src/budget-manager.ts +272 -0
- package/src/confidence-extractor.ts +321 -0
- package/src/consensus/synthesis.ts +2 -0
- package/src/consensus/voting.ts +22 -6
- package/src/context-tracker.ts +307 -0
- package/src/cost-tracker.ts +363 -0
- package/src/executor.ts +9 -0
- package/src/index.ts +72 -0
- package/src/participant-resolver.ts +297 -0
- package/src/patterns/round-robin.ts +48 -2
- package/src/patterns/synthesis.ts +89 -3
- package/src/prompts/templates.ts +4 -2
- package/src/provider-bridge.ts +52 -31
- package/src/recursive-executor.ts +510 -0
- package/src/types.ts +120 -0
package/dist/consensus/voting.js
CHANGED
|
@@ -3,8 +3,15 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Tallies votes from all providers and determines winner based on
|
|
5
5
|
* raw counts or confidence-weighted scores.
|
|
6
|
+
*
|
|
7
|
+
* Invariants:
|
|
8
|
+
* - INV-DISC-642: Agent responses weighted by agentWeightMultiplier (default 1.5x)
|
|
6
9
|
*/
|
|
7
10
|
import { VOTING_TALLY, interpolate, formatVotes, getProviderSystemPrompt, } from '../prompts/templates.js';
|
|
11
|
+
/**
|
|
12
|
+
* Default agent weight multiplier (INV-DISC-642)
|
|
13
|
+
*/
|
|
14
|
+
const DEFAULT_AGENT_WEIGHT = 1.5;
|
|
8
15
|
export class VotingConsensus {
|
|
9
16
|
method = 'voting';
|
|
10
17
|
async execute(context) {
|
|
@@ -23,8 +30,8 @@ export class VotingConsensus {
|
|
|
23
30
|
error: 'No valid votes found in discussion rounds',
|
|
24
31
|
};
|
|
25
32
|
}
|
|
26
|
-
// Tally votes
|
|
27
|
-
const votingResults = this.tallyVotes(votes,
|
|
33
|
+
// Tally votes with agent weight multiplier (INV-DISC-642)
|
|
34
|
+
const votingResults = this.tallyVotes(votes, context.agentWeightMultiplier);
|
|
28
35
|
// Generate synthesis summary
|
|
29
36
|
const synthesizerId = config.synthesizer ||
|
|
30
37
|
(participatingProviders.includes('claude') ? 'claude' : participatingProviders[0]) ||
|
|
@@ -58,6 +65,7 @@ export class VotingConsensus {
|
|
|
58
65
|
choice: response.vote,
|
|
59
66
|
confidence: response.confidence,
|
|
60
67
|
reasoning: this.extractReasoning(response.content),
|
|
68
|
+
isAgent: response.isAgent ?? false,
|
|
61
69
|
});
|
|
62
70
|
}
|
|
63
71
|
}
|
|
@@ -68,13 +76,16 @@ export class VotingConsensus {
|
|
|
68
76
|
const reasoningMatch = /reasoning:\s*(.+?)(?=\n\n|$)/is.exec(content);
|
|
69
77
|
return reasoningMatch?.[1] ? reasoningMatch[1].trim() : '';
|
|
70
78
|
}
|
|
71
|
-
tallyVotes(votes,
|
|
79
|
+
tallyVotes(votes, agentWeightMultiplier = DEFAULT_AGENT_WEIGHT) {
|
|
72
80
|
// Count raw votes
|
|
73
81
|
const rawVotes = {};
|
|
74
82
|
const weightedVotes = {};
|
|
75
83
|
for (const vote of votes) {
|
|
84
|
+
// Apply agent weight multiplier (INV-DISC-642)
|
|
85
|
+
const weight = vote.isAgent ? agentWeightMultiplier : 1.0;
|
|
86
|
+
const weightedConfidence = vote.confidence * weight;
|
|
76
87
|
rawVotes[vote.choice] = (rawVotes[vote.choice] || 0) + 1;
|
|
77
|
-
weightedVotes[vote.choice] = (weightedVotes[vote.choice] || 0) +
|
|
88
|
+
weightedVotes[vote.choice] = (weightedVotes[vote.choice] || 0) + weightedConfidence;
|
|
78
89
|
}
|
|
79
90
|
// Determine winner (by weighted votes)
|
|
80
91
|
let winner = '';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"voting.js","sourceRoot":"","sources":["../../src/consensus/voting.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"voting.js","sourceRoot":"","sources":["../../src/consensus/voting.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Discussion Context Tracker
|
|
3
|
+
*
|
|
4
|
+
* Tracks recursive discussion state including depth, budget, and call counts.
|
|
5
|
+
* Prevents infinite recursion and enforces resource limits.
|
|
6
|
+
*
|
|
7
|
+
* Invariants:
|
|
8
|
+
* - INV-DISC-600: Depth never exceeds maxDepth
|
|
9
|
+
* - INV-DISC-601: No circular discussions
|
|
10
|
+
* - INV-DISC-610: Child timeout ≤ parent remaining budget
|
|
11
|
+
* - INV-DISC-620: Total calls ≤ maxTotalCalls
|
|
12
|
+
*/
|
|
13
|
+
import { type DiscussionContext, type TimeoutConfig, type RecursiveConfig, type CostControlConfig } from '@defai.digital/contracts';
|
|
14
|
+
/**
|
|
15
|
+
* Result of checking if sub-discussion can be spawned
|
|
16
|
+
*/
|
|
17
|
+
export interface SubDiscussionCheck {
|
|
18
|
+
allowed: boolean;
|
|
19
|
+
reason?: string;
|
|
20
|
+
errorCode?: string;
|
|
21
|
+
availableBudgetMs?: number;
|
|
22
|
+
remainingCalls?: number;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Configuration for the context tracker
|
|
26
|
+
*/
|
|
27
|
+
export interface ContextTrackerConfig {
|
|
28
|
+
recursive: RecursiveConfig;
|
|
29
|
+
timeout: TimeoutConfig;
|
|
30
|
+
cost: CostControlConfig;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Discussion context tracker for managing recursive discussion state
|
|
34
|
+
*/
|
|
35
|
+
export interface DiscussionContextTracker {
|
|
36
|
+
/** Get current context */
|
|
37
|
+
getContext(): DiscussionContext;
|
|
38
|
+
/** Check if sub-discussion can be spawned */
|
|
39
|
+
canSpawnSubDiscussion(estimatedDurationMs?: number): SubDiscussionCheck;
|
|
40
|
+
/** Create child context for sub-discussion */
|
|
41
|
+
createChildContext(childDiscussionId: string): DiscussionContext;
|
|
42
|
+
/** Record provider calls made */
|
|
43
|
+
recordCalls(count: number): void;
|
|
44
|
+
/** Record time elapsed */
|
|
45
|
+
recordElapsed(elapsedMs: number): void;
|
|
46
|
+
/** Get timeout for current depth level */
|
|
47
|
+
getTimeoutForCurrentLevel(): number;
|
|
48
|
+
/** Get timeout for a specific depth level */
|
|
49
|
+
getTimeoutForLevel(depth: number): number;
|
|
50
|
+
/** Check if at root level */
|
|
51
|
+
isRoot(): boolean;
|
|
52
|
+
/** Get remaining depth capacity */
|
|
53
|
+
getRemainingDepth(): number;
|
|
54
|
+
/** Get remaining call capacity */
|
|
55
|
+
getRemainingCalls(): number;
|
|
56
|
+
/** Get remaining budget in milliseconds */
|
|
57
|
+
getRemainingBudgetMs(): number;
|
|
58
|
+
/** Get elapsed time since start */
|
|
59
|
+
getElapsedMs(): number;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Creates a discussion context tracker
|
|
63
|
+
*/
|
|
64
|
+
export declare function createContextTracker(discussionId: string, config?: Partial<ContextTrackerConfig>, parentContext?: DiscussionContext): DiscussionContextTracker;
|
|
65
|
+
/**
|
|
66
|
+
* Discussion context error
|
|
67
|
+
*/
|
|
68
|
+
export declare class DiscussionContextError extends Error {
|
|
69
|
+
readonly code: string;
|
|
70
|
+
readonly context?: DiscussionContext | undefined;
|
|
71
|
+
constructor(code: string, message: string, context?: DiscussionContext | undefined);
|
|
72
|
+
static maxDepthExceeded(context: DiscussionContext): DiscussionContextError;
|
|
73
|
+
static circularDiscussion(discussionId: string, context: DiscussionContext): DiscussionContextError;
|
|
74
|
+
static budgetExhausted(context: DiscussionContext): DiscussionContextError;
|
|
75
|
+
static maxCallsExceeded(context: DiscussionContext): DiscussionContextError;
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=context-tracker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context-tracker.d.ts","sourceRoot":"","sources":["../src/context-tracker.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EACL,KAAK,iBAAiB,EACtB,KAAK,aAAa,EAClB,KAAK,eAAe,EACpB,KAAK,iBAAiB,EAUvB,MAAM,0BAA0B,CAAC;AAElC;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,SAAS,EAAE,eAAe,CAAC;IAC3B,OAAO,EAAE,aAAa,CAAC;IACvB,IAAI,EAAE,iBAAiB,CAAC;CACzB;AAED;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACvC,0BAA0B;IAC1B,UAAU,IAAI,iBAAiB,CAAC;IAEhC,6CAA6C;IAC7C,qBAAqB,CAAC,mBAAmB,CAAC,EAAE,MAAM,GAAG,kBAAkB,CAAC;IAExE,8CAA8C;IAC9C,kBAAkB,CAAC,iBAAiB,EAAE,MAAM,GAAG,iBAAiB,CAAC;IAEjE,iCAAiC;IACjC,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAEjC,0BAA0B;IAC1B,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IAEvC,0CAA0C;IAC1C,yBAAyB,IAAI,MAAM,CAAC;IAEpC,6CAA6C;IAC7C,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC;IAE1C,6BAA6B;IAC7B,MAAM,IAAI,OAAO,CAAC;IAElB,mCAAmC;IACnC,iBAAiB,IAAI,MAAM,CAAC;IAE5B,kCAAkC;IAClC,iBAAiB,IAAI,MAAM,CAAC;IAE5B,2CAA2C;IAC3C,oBAAoB,IAAI,MAAM,CAAC;IAE/B,mCAAmC;IACnC,YAAY,IAAI,MAAM,CAAC;CACxB;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAClC,YAAY,EAAE,MAAM,EACpB,MAAM,GAAE,OAAO,CAAC,oBAAoB,CAAM,EAC1C,aAAa,CAAC,EAAE,iBAAiB,GAChC,wBAAwB,CAgK1B;AAED;;GAEG;AACH,qBAAa,sBAAuB,SAAQ,KAAK;aAE7B,IAAI,EAAE,MAAM;aAEZ,OAAO,CAAC,EAAE,iBAAiB;gBAF3B,IAAI,EAAE,MAAM,EAC5B,OAAO,EAAE,MAAM,EACC,OAAO,CAAC,EAAE,iBAAiB,YAAA;IAM7C,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,iBAAiB,GAAG,sBAAsB;IAQ3E,MAAM,CAAC,kBAAkB,CACvB,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,iBAAiB,GACzB,sBAAsB;IAQzB,MAAM,CAAC,eAAe,CAAC,OAAO,EAAE,iBAAiB,GAAG,sBAAsB;IAQ1E,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,iBAAiB,GAAG,sBAAsB;CAO5E"}
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Discussion Context Tracker
|
|
3
|
+
*
|
|
4
|
+
* Tracks recursive discussion state including depth, budget, and call counts.
|
|
5
|
+
* Prevents infinite recursion and enforces resource limits.
|
|
6
|
+
*
|
|
7
|
+
* Invariants:
|
|
8
|
+
* - INV-DISC-600: Depth never exceeds maxDepth
|
|
9
|
+
* - INV-DISC-601: No circular discussions
|
|
10
|
+
* - INV-DISC-610: Child timeout ≤ parent remaining budget
|
|
11
|
+
* - INV-DISC-620: Total calls ≤ maxTotalCalls
|
|
12
|
+
*/
|
|
13
|
+
import { DiscussionErrorCodes, createRootDiscussionContext, createChildDiscussionContext, canSpawnSubDiscussion, getTimeoutForLevel, DEFAULT_DISCUSSION_DEPTH, DEFAULT_TOTAL_BUDGET_MS, DEFAULT_MAX_TOTAL_CALLS, MIN_SYNTHESIS_TIME_MS, } from '@defai.digital/contracts';
|
|
14
|
+
/**
|
|
15
|
+
* Creates a discussion context tracker
|
|
16
|
+
*/
|
|
17
|
+
export function createContextTracker(discussionId, config = {}, parentContext) {
|
|
18
|
+
// Merge config with defaults
|
|
19
|
+
const recursiveConfig = {
|
|
20
|
+
enabled: config.recursive?.enabled ?? false,
|
|
21
|
+
maxDepth: config.recursive?.maxDepth ?? DEFAULT_DISCUSSION_DEPTH,
|
|
22
|
+
allowedProviders: config.recursive?.allowedProviders,
|
|
23
|
+
allowSubDiscussions: config.recursive?.allowSubDiscussions ?? true,
|
|
24
|
+
};
|
|
25
|
+
const timeoutConfig = {
|
|
26
|
+
strategy: config.timeout?.strategy ?? 'cascade',
|
|
27
|
+
totalBudgetMs: config.timeout?.totalBudgetMs ?? DEFAULT_TOTAL_BUDGET_MS,
|
|
28
|
+
minSynthesisMs: config.timeout?.minSynthesisMs ?? MIN_SYNTHESIS_TIME_MS,
|
|
29
|
+
levelTimeouts: config.timeout?.levelTimeouts,
|
|
30
|
+
};
|
|
31
|
+
const costConfig = {
|
|
32
|
+
maxTotalCalls: config.cost?.maxTotalCalls ?? DEFAULT_MAX_TOTAL_CALLS,
|
|
33
|
+
budgetUsd: config.cost?.budgetUsd,
|
|
34
|
+
cascadingConfidence: {
|
|
35
|
+
enabled: config.cost?.cascadingConfidence?.enabled ?? true,
|
|
36
|
+
threshold: config.cost?.cascadingConfidence?.threshold ?? 0.9,
|
|
37
|
+
minProviders: config.cost?.cascadingConfidence?.minProviders ?? 2,
|
|
38
|
+
},
|
|
39
|
+
};
|
|
40
|
+
// Initialize context
|
|
41
|
+
let context;
|
|
42
|
+
if (parentContext) {
|
|
43
|
+
// Create child context
|
|
44
|
+
const elapsed = Date.now() - new Date(parentContext.startedAt).getTime();
|
|
45
|
+
context = createChildDiscussionContext(parentContext, discussionId, elapsed, 0);
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
// Create root context
|
|
49
|
+
context = createRootDiscussionContext(discussionId, {
|
|
50
|
+
maxDepth: recursiveConfig.maxDepth,
|
|
51
|
+
totalBudgetMs: timeoutConfig.totalBudgetMs,
|
|
52
|
+
maxTotalCalls: costConfig.maxTotalCalls,
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
// Track mutable state
|
|
56
|
+
let totalCalls = context.totalCalls;
|
|
57
|
+
let elapsedSinceContextCreation = 0;
|
|
58
|
+
return {
|
|
59
|
+
getContext() {
|
|
60
|
+
return {
|
|
61
|
+
...context,
|
|
62
|
+
totalCalls,
|
|
63
|
+
remainingBudgetMs: Math.max(0, context.remainingBudgetMs - elapsedSinceContextCreation),
|
|
64
|
+
};
|
|
65
|
+
},
|
|
66
|
+
canSpawnSubDiscussion(estimatedDurationMs) {
|
|
67
|
+
// Check if recursion is enabled
|
|
68
|
+
if (!recursiveConfig.enabled) {
|
|
69
|
+
return {
|
|
70
|
+
allowed: false,
|
|
71
|
+
reason: 'Recursive discussions not enabled',
|
|
72
|
+
errorCode: DiscussionErrorCodes.INVALID_CONFIG,
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
// Check if sub-discussions allowed
|
|
76
|
+
if (!recursiveConfig.allowSubDiscussions) {
|
|
77
|
+
return {
|
|
78
|
+
allowed: false,
|
|
79
|
+
reason: 'Sub-discussions not allowed in configuration',
|
|
80
|
+
errorCode: DiscussionErrorCodes.INVALID_CONFIG,
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
// Use contract function for basic checks
|
|
84
|
+
const remainingBudget = context.remainingBudgetMs - elapsedSinceContextCreation;
|
|
85
|
+
const minBudget = estimatedDurationMs ?? timeoutConfig.minSynthesisMs * 2;
|
|
86
|
+
const checkContext = {
|
|
87
|
+
...context,
|
|
88
|
+
totalCalls,
|
|
89
|
+
remainingBudgetMs: remainingBudget,
|
|
90
|
+
};
|
|
91
|
+
const check = canSpawnSubDiscussion(checkContext, minBudget);
|
|
92
|
+
if (!check.allowed) {
|
|
93
|
+
// Determine error code based on reason
|
|
94
|
+
const reason = check.reason ?? 'Sub-discussion not allowed';
|
|
95
|
+
let errorCode = DiscussionErrorCodes.INVALID_CONFIG;
|
|
96
|
+
if (reason.includes('depth')) {
|
|
97
|
+
errorCode = DiscussionErrorCodes.MAX_DEPTH_EXCEEDED;
|
|
98
|
+
}
|
|
99
|
+
else if (reason.includes('budget')) {
|
|
100
|
+
errorCode = DiscussionErrorCodes.BUDGET_EXHAUSTED;
|
|
101
|
+
}
|
|
102
|
+
else if (reason.includes('calls')) {
|
|
103
|
+
errorCode = DiscussionErrorCodes.MAX_CALLS_EXCEEDED;
|
|
104
|
+
}
|
|
105
|
+
return {
|
|
106
|
+
allowed: false,
|
|
107
|
+
reason,
|
|
108
|
+
errorCode,
|
|
109
|
+
availableBudgetMs: remainingBudget,
|
|
110
|
+
remainingCalls: context.maxTotalCalls - totalCalls,
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
return {
|
|
114
|
+
allowed: true,
|
|
115
|
+
availableBudgetMs: remainingBudget,
|
|
116
|
+
remainingCalls: context.maxTotalCalls - totalCalls,
|
|
117
|
+
};
|
|
118
|
+
},
|
|
119
|
+
createChildContext(childDiscussionId) {
|
|
120
|
+
const elapsed = Date.now() - new Date(context.startedAt).getTime();
|
|
121
|
+
return createChildDiscussionContext({ ...context, totalCalls }, childDiscussionId, elapsed, 0);
|
|
122
|
+
},
|
|
123
|
+
recordCalls(count) {
|
|
124
|
+
totalCalls += count;
|
|
125
|
+
},
|
|
126
|
+
recordElapsed(elapsedMs) {
|
|
127
|
+
elapsedSinceContextCreation += elapsedMs;
|
|
128
|
+
},
|
|
129
|
+
getTimeoutForCurrentLevel() {
|
|
130
|
+
return getTimeoutForLevel(timeoutConfig, context.depth, context.maxDepth);
|
|
131
|
+
},
|
|
132
|
+
getTimeoutForLevel(depth) {
|
|
133
|
+
return getTimeoutForLevel(timeoutConfig, depth, context.maxDepth);
|
|
134
|
+
},
|
|
135
|
+
isRoot() {
|
|
136
|
+
return context.depth === 0;
|
|
137
|
+
},
|
|
138
|
+
getRemainingDepth() {
|
|
139
|
+
return context.maxDepth - context.depth;
|
|
140
|
+
},
|
|
141
|
+
getRemainingCalls() {
|
|
142
|
+
return Math.max(0, context.maxTotalCalls - totalCalls);
|
|
143
|
+
},
|
|
144
|
+
getRemainingBudgetMs() {
|
|
145
|
+
return Math.max(0, context.remainingBudgetMs - elapsedSinceContextCreation);
|
|
146
|
+
},
|
|
147
|
+
getElapsedMs() {
|
|
148
|
+
return Date.now() - new Date(context.startedAt).getTime();
|
|
149
|
+
},
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Discussion context error
|
|
154
|
+
*/
|
|
155
|
+
export class DiscussionContextError extends Error {
|
|
156
|
+
code;
|
|
157
|
+
context;
|
|
158
|
+
constructor(code, message, context) {
|
|
159
|
+
super(message);
|
|
160
|
+
this.code = code;
|
|
161
|
+
this.context = context;
|
|
162
|
+
this.name = 'DiscussionContextError';
|
|
163
|
+
}
|
|
164
|
+
static maxDepthExceeded(context) {
|
|
165
|
+
return new DiscussionContextError(DiscussionErrorCodes.MAX_DEPTH_EXCEEDED, `Maximum discussion depth ${context.maxDepth} exceeded at depth ${context.depth}`, context);
|
|
166
|
+
}
|
|
167
|
+
static circularDiscussion(discussionId, context) {
|
|
168
|
+
return new DiscussionContextError(DiscussionErrorCodes.CIRCULAR_DISCUSSION, `Circular discussion detected: ${discussionId} already in chain`, context);
|
|
169
|
+
}
|
|
170
|
+
static budgetExhausted(context) {
|
|
171
|
+
return new DiscussionContextError(DiscussionErrorCodes.BUDGET_EXHAUSTED, `Timeout budget exhausted: ${context.remainingBudgetMs}ms remaining`, context);
|
|
172
|
+
}
|
|
173
|
+
static maxCallsExceeded(context) {
|
|
174
|
+
return new DiscussionContextError(DiscussionErrorCodes.MAX_CALLS_EXCEEDED, `Maximum calls ${context.maxTotalCalls} exceeded`, context);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
//# sourceMappingURL=context-tracker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context-tracker.js","sourceRoot":"","sources":["../src/context-tracker.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Discussion Cost Tracker
|
|
3
|
+
*
|
|
4
|
+
* Tracks costs and resource usage across discussion execution.
|
|
5
|
+
* Enforces budget limits and provides visibility into spending.
|
|
6
|
+
*
|
|
7
|
+
* Invariants:
|
|
8
|
+
* - INV-DISC-620: Total calls ≤ maxTotalCalls
|
|
9
|
+
* - INV-DISC-621: Abort if cost budget exceeded
|
|
10
|
+
*/
|
|
11
|
+
import type { CostControlConfig } from '@defai.digital/contracts';
|
|
12
|
+
/**
|
|
13
|
+
* Cost per provider (approximate, in USD per 1K tokens)
|
|
14
|
+
* These are rough estimates for planning purposes
|
|
15
|
+
*/
|
|
16
|
+
export declare const PROVIDER_COSTS: Record<string, {
|
|
17
|
+
input: number;
|
|
18
|
+
output: number;
|
|
19
|
+
}>;
|
|
20
|
+
/**
|
|
21
|
+
* Provider call record
|
|
22
|
+
*/
|
|
23
|
+
export interface ProviderCallRecord {
|
|
24
|
+
/** Provider ID */
|
|
25
|
+
providerId: string;
|
|
26
|
+
/** Input tokens */
|
|
27
|
+
inputTokens: number;
|
|
28
|
+
/** Output tokens */
|
|
29
|
+
outputTokens: number;
|
|
30
|
+
/** Duration in milliseconds */
|
|
31
|
+
durationMs: number;
|
|
32
|
+
/** Estimated cost in USD */
|
|
33
|
+
estimatedCostUsd: number;
|
|
34
|
+
/** Discussion depth where call occurred */
|
|
35
|
+
depth: number;
|
|
36
|
+
/** Timestamp */
|
|
37
|
+
timestamp: string;
|
|
38
|
+
/** Whether call succeeded */
|
|
39
|
+
success: boolean;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Cost tracking summary
|
|
43
|
+
*/
|
|
44
|
+
export interface CostSummary {
|
|
45
|
+
/** Total provider calls made */
|
|
46
|
+
totalCalls: number;
|
|
47
|
+
/** Total input tokens */
|
|
48
|
+
totalInputTokens: number;
|
|
49
|
+
/** Total output tokens */
|
|
50
|
+
totalOutputTokens: number;
|
|
51
|
+
/** Total estimated cost in USD */
|
|
52
|
+
totalCostUsd: number;
|
|
53
|
+
/** Cost breakdown by provider */
|
|
54
|
+
byProvider: Record<string, {
|
|
55
|
+
calls: number;
|
|
56
|
+
inputTokens: number;
|
|
57
|
+
outputTokens: number;
|
|
58
|
+
costUsd: number;
|
|
59
|
+
}>;
|
|
60
|
+
/** Cost breakdown by depth level */
|
|
61
|
+
byDepth: Record<number, {
|
|
62
|
+
calls: number;
|
|
63
|
+
costUsd: number;
|
|
64
|
+
}>;
|
|
65
|
+
/** Whether budget limit was exceeded */
|
|
66
|
+
budgetExceeded: boolean;
|
|
67
|
+
/** Whether call limit was exceeded */
|
|
68
|
+
callLimitExceeded: boolean;
|
|
69
|
+
/** Remaining budget (if configured) */
|
|
70
|
+
remainingBudgetUsd: number | undefined;
|
|
71
|
+
/** Remaining calls */
|
|
72
|
+
remainingCalls: number;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Budget check result
|
|
76
|
+
*/
|
|
77
|
+
export interface BudgetCheckResult {
|
|
78
|
+
/** Whether operation is allowed */
|
|
79
|
+
allowed: boolean;
|
|
80
|
+
/** Reason if not allowed */
|
|
81
|
+
reason?: string;
|
|
82
|
+
/** Current usage metrics */
|
|
83
|
+
currentCalls: number;
|
|
84
|
+
currentCostUsd: number;
|
|
85
|
+
/** Estimated cost of proposed operation */
|
|
86
|
+
estimatedCostUsd?: number;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Discussion cost tracker interface
|
|
90
|
+
*/
|
|
91
|
+
export interface DiscussionCostTracker {
|
|
92
|
+
/** Record a provider call */
|
|
93
|
+
recordCall(record: Omit<ProviderCallRecord, 'estimatedCostUsd' | 'timestamp'>): void;
|
|
94
|
+
/** Check if a call is within budget */
|
|
95
|
+
checkBudget(providerId: string, estimatedTokens?: number): BudgetCheckResult;
|
|
96
|
+
/** Get current cost summary */
|
|
97
|
+
getSummary(): CostSummary;
|
|
98
|
+
/** Get total calls made */
|
|
99
|
+
getTotalCalls(): number;
|
|
100
|
+
/** Get remaining calls */
|
|
101
|
+
getRemainingCalls(): number;
|
|
102
|
+
/** Check if budget exceeded */
|
|
103
|
+
isBudgetExceeded(): boolean;
|
|
104
|
+
/** Check if call limit exceeded */
|
|
105
|
+
isCallLimitExceeded(): boolean;
|
|
106
|
+
/** Estimate cost for a provider call */
|
|
107
|
+
estimateCost(providerId: string, inputTokens: number, outputTokens: number): number;
|
|
108
|
+
/** Create child tracker for sub-discussion */
|
|
109
|
+
createChildTracker(depth: number): DiscussionCostTracker;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Create a cost tracker for a discussion
|
|
113
|
+
*/
|
|
114
|
+
export declare function createCostTracker(config: CostControlConfig, parentTracker?: DiscussionCostTracker): DiscussionCostTracker;
|
|
115
|
+
/**
|
|
116
|
+
* Format cost for display
|
|
117
|
+
*/
|
|
118
|
+
export declare function formatCost(costUsd: number): string;
|
|
119
|
+
/**
|
|
120
|
+
* Format cost summary for CLI/logs
|
|
121
|
+
*/
|
|
122
|
+
export declare function formatCostSummary(summary: CostSummary): string;
|
|
123
|
+
//# sourceMappingURL=cost-tracker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cost-tracker.d.ts","sourceRoot":"","sources":["../src/cost-tracker.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAGlE;;;GAGG;AACH,eAAO,MAAM,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAO5E,CAAC;AAOF;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,kBAAkB;IAClB,UAAU,EAAE,MAAM,CAAC;IAEnB,mBAAmB;IACnB,WAAW,EAAE,MAAM,CAAC;IAEpB,oBAAoB;IACpB,YAAY,EAAE,MAAM,CAAC;IAErB,+BAA+B;IAC/B,UAAU,EAAE,MAAM,CAAC;IAEnB,4BAA4B;IAC5B,gBAAgB,EAAE,MAAM,CAAC;IAEzB,2CAA2C;IAC3C,KAAK,EAAE,MAAM,CAAC;IAEd,gBAAgB;IAChB,SAAS,EAAE,MAAM,CAAC;IAElB,6BAA6B;IAC7B,OAAO,EAAE,OAAO,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,gCAAgC;IAChC,UAAU,EAAE,MAAM,CAAC;IAEnB,yBAAyB;IACzB,gBAAgB,EAAE,MAAM,CAAC;IAEzB,0BAA0B;IAC1B,iBAAiB,EAAE,MAAM,CAAC;IAE1B,kCAAkC;IAClC,YAAY,EAAE,MAAM,CAAC;IAErB,iCAAiC;IACjC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE;QACzB,KAAK,EAAE,MAAM,CAAC;QACd,WAAW,EAAE,MAAM,CAAC;QACpB,YAAY,EAAE,MAAM,CAAC;QACrB,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC,CAAC;IAEH,oCAAoC;IACpC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE;QACtB,KAAK,EAAE,MAAM,CAAC;QACd,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC,CAAC;IAEH,wCAAwC;IACxC,cAAc,EAAE,OAAO,CAAC;IAExB,sCAAsC;IACtC,iBAAiB,EAAE,OAAO,CAAC;IAE3B,uCAAuC;IACvC,kBAAkB,EAAE,MAAM,GAAG,SAAS,CAAC;IAEvC,sBAAsB;IACtB,cAAc,EAAE,MAAM,CAAC;CACxB;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,mCAAmC;IACnC,OAAO,EAAE,OAAO,CAAC;IAEjB,4BAA4B;IAC5B,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB,4BAA4B;IAC5B,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;IAEvB,2CAA2C;IAC3C,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,6BAA6B;IAC7B,UAAU,CAAC,MAAM,EAAE,IAAI,CAAC,kBAAkB,EAAE,kBAAkB,GAAG,WAAW,CAAC,GAAG,IAAI,CAAC;IAErF,uCAAuC;IACvC,WAAW,CAAC,UAAU,EAAE,MAAM,EAAE,eAAe,CAAC,EAAE,MAAM,GAAG,iBAAiB,CAAC;IAE7E,+BAA+B;IAC/B,UAAU,IAAI,WAAW,CAAC;IAE1B,2BAA2B;IAC3B,aAAa,IAAI,MAAM,CAAC;IAExB,0BAA0B;IAC1B,iBAAiB,IAAI,MAAM,CAAC;IAE5B,+BAA+B;IAC/B,gBAAgB,IAAI,OAAO,CAAC;IAE5B,mCAAmC;IACnC,mBAAmB,IAAI,OAAO,CAAC;IAE/B,wCAAwC;IACxC,YAAY,CAAC,UAAU,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,MAAM,CAAC;IAEpF,8CAA8C;IAC9C,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,qBAAqB,CAAC;CAC1D;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,iBAAiB,EACzB,aAAa,CAAC,EAAE,qBAAqB,GACpC,qBAAqB,CAoJvB;AAkBD;;GAEG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAMlD;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,WAAW,GAAG,MAAM,CAsB9D"}
|