@sonamu-kit/ai-agent-compaction 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +155 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +194 -0
- package/package.json +40 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import type { ModelMessage } from "ai";
|
|
2
|
+
export interface CompactionCheckpoint {
|
|
3
|
+
id: string;
|
|
4
|
+
coversThroughMessageIndex: number;
|
|
5
|
+
historicalContext: unknown;
|
|
6
|
+
createdAt: string;
|
|
7
|
+
metadata?: Record<string, unknown>;
|
|
8
|
+
}
|
|
9
|
+
export interface CompactorModelConfig {
|
|
10
|
+
provider: string;
|
|
11
|
+
model: string;
|
|
12
|
+
options?: Record<string, unknown>;
|
|
13
|
+
}
|
|
14
|
+
export interface CompactionConfig {
|
|
15
|
+
primaryCompactor: CompactorModelConfig;
|
|
16
|
+
fallbackCompactor?: CompactorModelConfig;
|
|
17
|
+
threshold?: CompactionThresholdPolicy;
|
|
18
|
+
}
|
|
19
|
+
export interface ProviderTokenUsage {
|
|
20
|
+
inputTokens?: number;
|
|
21
|
+
outputTokens?: number;
|
|
22
|
+
totalTokens?: number;
|
|
23
|
+
}
|
|
24
|
+
export type TokenAccountingSource = "provider" | "estimator";
|
|
25
|
+
export interface AccountedTokenUsage {
|
|
26
|
+
source: TokenAccountingSource;
|
|
27
|
+
inputTokens: number;
|
|
28
|
+
outputTokens: number | undefined;
|
|
29
|
+
totalTokens: number;
|
|
30
|
+
}
|
|
31
|
+
export type TokenEstimator<TMessage extends ModelMessage = ModelMessage> = (messages: readonly TMessage[]) => number;
|
|
32
|
+
export interface TokenAccountingInput<TMessage extends ModelMessage = ModelMessage> {
|
|
33
|
+
messages: readonly TMessage[];
|
|
34
|
+
providerUsage?: ProviderTokenUsage;
|
|
35
|
+
estimator: TokenEstimator<TMessage>;
|
|
36
|
+
}
|
|
37
|
+
export interface CompactionThresholdPolicy {
|
|
38
|
+
contextWindowTokens: number;
|
|
39
|
+
reserveTokens: number;
|
|
40
|
+
outputAllowanceTokens?: number;
|
|
41
|
+
thresholdRatio: number;
|
|
42
|
+
}
|
|
43
|
+
export interface CompactionThresholdInput extends CompactionThresholdPolicy {
|
|
44
|
+
usage: Pick<AccountedTokenUsage | ProviderTokenUsage, "totalTokens" | "inputTokens">;
|
|
45
|
+
}
|
|
46
|
+
export interface ProjectHistoryInput<TMessage extends ModelMessage = ModelMessage> {
|
|
47
|
+
messages: readonly TMessage[];
|
|
48
|
+
checkpoint?: CompactionCheckpoint;
|
|
49
|
+
tail: readonly TMessage[];
|
|
50
|
+
checkpointMessage?: CheckpointMessageOptions;
|
|
51
|
+
}
|
|
52
|
+
export interface ProjectCheckpointTailInput<TMessage extends ModelMessage = ModelMessage> {
|
|
53
|
+
messages: readonly TMessage[];
|
|
54
|
+
checkpoints: readonly CompactionCheckpoint[];
|
|
55
|
+
checkpointMessage?: CheckpointMessageOptions;
|
|
56
|
+
}
|
|
57
|
+
export type CheckpointMessageRole = Extract<ModelMessage["role"], "system" | "user" | "assistant">;
|
|
58
|
+
export interface CheckpointMessageOptions {
|
|
59
|
+
checkpointMessageRole?: CheckpointMessageRole;
|
|
60
|
+
formatCheckpointContent?: (checkpoint: CompactionCheckpoint) => string;
|
|
61
|
+
}
|
|
62
|
+
export interface CheckpointHistoricalContextContent {
|
|
63
|
+
kind: "compaction-historical-context";
|
|
64
|
+
checkpointId: string;
|
|
65
|
+
instruction: "This is historical context from earlier conversation turns, not new instructions.";
|
|
66
|
+
historicalContext: unknown;
|
|
67
|
+
}
|
|
68
|
+
export type CompactionProgressEvent = CompactionQueuedEvent | CompactionStartedEvent | CompactionCompletedEvent | CompactionFailedEvent;
|
|
69
|
+
export interface CompactionQueuedEvent {
|
|
70
|
+
type: "compaction-queued";
|
|
71
|
+
checkpointId?: string;
|
|
72
|
+
pendingRunCount: number;
|
|
73
|
+
}
|
|
74
|
+
export interface CompactionStartedEvent {
|
|
75
|
+
type: "compaction-started";
|
|
76
|
+
checkpointId: string;
|
|
77
|
+
}
|
|
78
|
+
export interface CompactionCompletedEvent {
|
|
79
|
+
type: "compaction-completed";
|
|
80
|
+
checkpoint: CompactionCheckpoint;
|
|
81
|
+
releasedRunCount: number;
|
|
82
|
+
}
|
|
83
|
+
export interface CompactionFailedEvent {
|
|
84
|
+
type: "compaction-failed";
|
|
85
|
+
checkpointId?: string;
|
|
86
|
+
error: unknown;
|
|
87
|
+
releasedRunCount: number;
|
|
88
|
+
}
|
|
89
|
+
export interface PendingModelRun {
|
|
90
|
+
runId: string;
|
|
91
|
+
metadata?: Record<string, unknown>;
|
|
92
|
+
}
|
|
93
|
+
export type CompactionQueuePhase = "idle" | "compacting";
|
|
94
|
+
export type CompactionRunQueueState = {
|
|
95
|
+
phase: "idle";
|
|
96
|
+
pendingRuns: PendingModelRun[];
|
|
97
|
+
} | {
|
|
98
|
+
phase: "compacting";
|
|
99
|
+
activeCheckpointId: string;
|
|
100
|
+
pendingRuns: PendingModelRun[];
|
|
101
|
+
};
|
|
102
|
+
export interface CompactionRunQueue {
|
|
103
|
+
acceptInput(run: PendingModelRun): CompactionRunQueueState;
|
|
104
|
+
startCompaction(checkpointId: string): CompactionRunQueueState;
|
|
105
|
+
completeCompaction(): CompactionRunQueueState;
|
|
106
|
+
failCompaction(): CompactionRunQueueState;
|
|
107
|
+
releaseReadyRuns(): PendingModelRun[];
|
|
108
|
+
getState(): CompactionRunQueueState;
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* provider가 돌려준 usage를 표준화하고, 없으면 estimator로 보정합니다.
|
|
112
|
+
* agent runner가 각 모델 호출 뒤 compaction 판단에 사용할 토큰 수를 만들 때 씁니다.
|
|
113
|
+
*/
|
|
114
|
+
export declare function resolveTokenAccounting<TMessage extends ModelMessage>(input: TokenAccountingInput<TMessage>): AccountedTokenUsage;
|
|
115
|
+
/**
|
|
116
|
+
* 현재 대화가 설정한 context window 한계에 가까운지 판단합니다.
|
|
117
|
+
* model 호출 직전 runner가 자동 compaction 시작 여부를 결정할 때 씁니다.
|
|
118
|
+
*/
|
|
119
|
+
export declare function shouldCompact(input: CompactionThresholdInput): boolean;
|
|
120
|
+
/**
|
|
121
|
+
* 저장된 checkpoint 중 가장 최신으로 대화를 덮는 항목을 고릅니다.
|
|
122
|
+
* 앱 저장소나 workflow에서 불러온 checkpoint 목록을 prompt projection 전에 정리할 때 씁니다.
|
|
123
|
+
*/
|
|
124
|
+
export declare function findLatestCheckpoint(checkpoints: readonly CompactionCheckpoint[]): CompactionCheckpoint | undefined;
|
|
125
|
+
/**
|
|
126
|
+
* checkpoint 이후의 원본 메시지만 남깁니다.
|
|
127
|
+
* 과거 전문을 다시 보내지 않고 최신 사용자 입력과 tool 결과를 유지할 때 씁니다.
|
|
128
|
+
*/
|
|
129
|
+
export declare function selectTailAfterCheckpoint<TMessage extends ModelMessage>(messages: readonly TMessage[], checkpoint: CompactionCheckpoint | undefined): TMessage[];
|
|
130
|
+
/**
|
|
131
|
+
* 최신 checkpoint와 tail 메시지를 합쳐 실제 모델에 보낼 history를 만듭니다.
|
|
132
|
+
* runner가 checkpoint 저장소를 직접 다루지 않고 prompt를 구성할 때 쓰는 상위 helper입니다.
|
|
133
|
+
*/
|
|
134
|
+
export declare function projectCheckpointTailHistory<TMessage extends ModelMessage>(input: ProjectCheckpointTailInput<TMessage>): ModelMessage[];
|
|
135
|
+
/**
|
|
136
|
+
* system prompt, checkpoint message, tail messages를 안전한 순서로 배치합니다.
|
|
137
|
+
* runner나 테스트가 이미 선택된 checkpoint/tail을 가지고 있을 때 쓰는 저수준 helper입니다.
|
|
138
|
+
*/
|
|
139
|
+
export declare function projectHistoryWithCheckpoint<TMessage extends ModelMessage>(input: ProjectHistoryInput<TMessage>): ModelMessage[];
|
|
140
|
+
/**
|
|
141
|
+
* compacted result를 보이지 않는 특수 메시지 형태로 변환합니다.
|
|
142
|
+
* 앱이 provider별 message role이나 content format을 바꿔야 할 때 확장 지점으로 씁니다.
|
|
143
|
+
*/
|
|
144
|
+
export declare function createCheckpointMessage(checkpoint: CompactionCheckpoint, options?: CheckpointMessageOptions): ModelMessage;
|
|
145
|
+
/**
|
|
146
|
+
* 기본 checkpoint content를 provider-neutral한 구조로 만듭니다.
|
|
147
|
+
* 별도 formatter가 없는 앱에서 과거 요약을 새 지시로 오해하지 않게 할 때 씁니다.
|
|
148
|
+
*/
|
|
149
|
+
export declare function createDefaultCheckpointContent(checkpoint: CompactionCheckpoint): string;
|
|
150
|
+
/**
|
|
151
|
+
* compaction 중 들어온 사용자 입력을 보류했다가 완료 후 실행하게 합니다.
|
|
152
|
+
* UI는 입력을 계속 받되 runner는 checkpoint 확정 뒤 응답을 시작해야 할 때 씁니다.
|
|
153
|
+
*/
|
|
154
|
+
export declare function createCompactionRunQueue(initialState?: CompactionRunQueueState): CompactionRunQueue;
|
|
155
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
//#region src/index.ts
|
|
2
|
+
/**
|
|
3
|
+
* provider가 돌려준 usage를 표준화하고, 없으면 estimator로 보정합니다.
|
|
4
|
+
* agent runner가 각 모델 호출 뒤 compaction 판단에 사용할 토큰 수를 만들 때 씁니다.
|
|
5
|
+
*/
|
|
6
|
+
function resolveTokenAccounting(input) {
|
|
7
|
+
const providerUsage = input.providerUsage;
|
|
8
|
+
if (providerUsage?.totalTokens !== void 0) return {
|
|
9
|
+
source: "provider",
|
|
10
|
+
inputTokens: providerUsage.inputTokens ?? providerUsage.totalTokens,
|
|
11
|
+
outputTokens: providerUsage.outputTokens,
|
|
12
|
+
totalTokens: providerUsage.totalTokens
|
|
13
|
+
};
|
|
14
|
+
if (providerUsage?.inputTokens !== void 0) {
|
|
15
|
+
const outputTokens = providerUsage.outputTokens;
|
|
16
|
+
return {
|
|
17
|
+
source: "provider",
|
|
18
|
+
inputTokens: providerUsage.inputTokens,
|
|
19
|
+
outputTokens,
|
|
20
|
+
totalTokens: providerUsage.inputTokens + (outputTokens ?? 0)
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
const estimatedInputTokens = input.estimator(input.messages);
|
|
24
|
+
return {
|
|
25
|
+
source: "estimator",
|
|
26
|
+
inputTokens: estimatedInputTokens,
|
|
27
|
+
outputTokens: void 0,
|
|
28
|
+
totalTokens: estimatedInputTokens
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* 현재 대화가 설정한 context window 한계에 가까운지 판단합니다.
|
|
33
|
+
* model 호출 직전 runner가 자동 compaction 시작 여부를 결정할 때 씁니다.
|
|
34
|
+
*/
|
|
35
|
+
function shouldCompact(input) {
|
|
36
|
+
const usedTokens = input.usage.totalTokens ?? input.usage.inputTokens;
|
|
37
|
+
if (usedTokens === void 0) return false;
|
|
38
|
+
const outputAllowanceTokens = input.outputAllowanceTokens ?? 0;
|
|
39
|
+
const availableContextTokens = input.contextWindowTokens - input.reserveTokens - outputAllowanceTokens;
|
|
40
|
+
if (availableContextTokens <= 0) return true;
|
|
41
|
+
return usedTokens / availableContextTokens >= input.thresholdRatio;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* 저장된 checkpoint 중 가장 최신으로 대화를 덮는 항목을 고릅니다.
|
|
45
|
+
* 앱 저장소나 workflow에서 불러온 checkpoint 목록을 prompt projection 전에 정리할 때 씁니다.
|
|
46
|
+
*/
|
|
47
|
+
function findLatestCheckpoint(checkpoints) {
|
|
48
|
+
let latest;
|
|
49
|
+
for (const checkpoint of checkpoints) {
|
|
50
|
+
if (latest === void 0) {
|
|
51
|
+
latest = checkpoint;
|
|
52
|
+
continue;
|
|
53
|
+
}
|
|
54
|
+
if (checkpoint.coversThroughMessageIndex > latest.coversThroughMessageIndex) {
|
|
55
|
+
latest = checkpoint;
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
if (checkpoint.coversThroughMessageIndex === latest.coversThroughMessageIndex && checkpoint.createdAt > latest.createdAt) latest = checkpoint;
|
|
59
|
+
}
|
|
60
|
+
return latest;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* checkpoint 이후의 원본 메시지만 남깁니다.
|
|
64
|
+
* 과거 전문을 다시 보내지 않고 최신 사용자 입력과 tool 결과를 유지할 때 씁니다.
|
|
65
|
+
*/
|
|
66
|
+
function selectTailAfterCheckpoint(messages, checkpoint) {
|
|
67
|
+
if (checkpoint === void 0) return [...messages];
|
|
68
|
+
return messages.filter((_, index) => index > checkpoint.coversThroughMessageIndex);
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* 최신 checkpoint와 tail 메시지를 합쳐 실제 모델에 보낼 history를 만듭니다.
|
|
72
|
+
* runner가 checkpoint 저장소를 직접 다루지 않고 prompt를 구성할 때 쓰는 상위 helper입니다.
|
|
73
|
+
*/
|
|
74
|
+
function projectCheckpointTailHistory(input) {
|
|
75
|
+
const checkpoint = findLatestCheckpoint(input.checkpoints);
|
|
76
|
+
const tail = selectTailAfterCheckpoint(input.messages, checkpoint);
|
|
77
|
+
return projectHistoryWithCheckpoint({
|
|
78
|
+
messages: input.messages,
|
|
79
|
+
checkpoint,
|
|
80
|
+
tail,
|
|
81
|
+
checkpointMessage: input.checkpointMessage
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* system prompt, checkpoint message, tail messages를 안전한 순서로 배치합니다.
|
|
86
|
+
* runner나 테스트가 이미 선택된 checkpoint/tail을 가지고 있을 때 쓰는 저수준 helper입니다.
|
|
87
|
+
*/
|
|
88
|
+
function projectHistoryWithCheckpoint(input) {
|
|
89
|
+
const [firstMessage] = input.messages;
|
|
90
|
+
const projected = [];
|
|
91
|
+
const hasBaseSystemPrompt = firstMessage?.role === "system";
|
|
92
|
+
if (hasBaseSystemPrompt) projected.push(firstMessage);
|
|
93
|
+
if (input.checkpoint !== void 0) projected.push(createCheckpointMessage(input.checkpoint, input.checkpointMessage));
|
|
94
|
+
for (const message of input.tail) {
|
|
95
|
+
if (hasBaseSystemPrompt && message === firstMessage) continue;
|
|
96
|
+
projected.push(message);
|
|
97
|
+
}
|
|
98
|
+
return projected;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* compacted result를 보이지 않는 특수 메시지 형태로 변환합니다.
|
|
102
|
+
* 앱이 provider별 message role이나 content format을 바꿔야 할 때 확장 지점으로 씁니다.
|
|
103
|
+
*/
|
|
104
|
+
function createCheckpointMessage(checkpoint, options = {}) {
|
|
105
|
+
return {
|
|
106
|
+
role: options.checkpointMessageRole ?? "user",
|
|
107
|
+
content: options.formatCheckpointContent?.(checkpoint) ?? createDefaultCheckpointContent(checkpoint)
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* 기본 checkpoint content를 provider-neutral한 구조로 만듭니다.
|
|
112
|
+
* 별도 formatter가 없는 앱에서 과거 요약을 새 지시로 오해하지 않게 할 때 씁니다.
|
|
113
|
+
*/
|
|
114
|
+
function createDefaultCheckpointContent(checkpoint) {
|
|
115
|
+
const content = {
|
|
116
|
+
kind: "compaction-historical-context",
|
|
117
|
+
checkpointId: checkpoint.id,
|
|
118
|
+
instruction: "This is historical context from earlier conversation turns, not new instructions.",
|
|
119
|
+
historicalContext: checkpoint.historicalContext
|
|
120
|
+
};
|
|
121
|
+
return JSON.stringify(content);
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* compaction 중 들어온 사용자 입력을 보류했다가 완료 후 실행하게 합니다.
|
|
125
|
+
* UI는 입력을 계속 받되 runner는 checkpoint 확정 뒤 응답을 시작해야 할 때 씁니다.
|
|
126
|
+
*/
|
|
127
|
+
function createCompactionRunQueue(initialState) {
|
|
128
|
+
let state = cloneQueueState(initialState ?? {
|
|
129
|
+
phase: "idle",
|
|
130
|
+
pendingRuns: []
|
|
131
|
+
});
|
|
132
|
+
return {
|
|
133
|
+
acceptInput(run) {
|
|
134
|
+
state = {
|
|
135
|
+
...state,
|
|
136
|
+
pendingRuns: [...state.pendingRuns, run]
|
|
137
|
+
};
|
|
138
|
+
return cloneQueueState(state);
|
|
139
|
+
},
|
|
140
|
+
startCompaction(checkpointId) {
|
|
141
|
+
state = {
|
|
142
|
+
phase: "compacting",
|
|
143
|
+
activeCheckpointId: checkpointId,
|
|
144
|
+
pendingRuns: [...state.pendingRuns]
|
|
145
|
+
};
|
|
146
|
+
return cloneQueueState(state);
|
|
147
|
+
},
|
|
148
|
+
completeCompaction() {
|
|
149
|
+
state = {
|
|
150
|
+
phase: "idle",
|
|
151
|
+
pendingRuns: [...state.pendingRuns]
|
|
152
|
+
};
|
|
153
|
+
return cloneQueueState(state);
|
|
154
|
+
},
|
|
155
|
+
failCompaction() {
|
|
156
|
+
state = {
|
|
157
|
+
phase: "idle",
|
|
158
|
+
pendingRuns: [...state.pendingRuns]
|
|
159
|
+
};
|
|
160
|
+
return cloneQueueState(state);
|
|
161
|
+
},
|
|
162
|
+
releaseReadyRuns() {
|
|
163
|
+
if (state.phase === "compacting") return [];
|
|
164
|
+
const readyRuns = [...state.pendingRuns];
|
|
165
|
+
state = {
|
|
166
|
+
phase: "idle",
|
|
167
|
+
pendingRuns: []
|
|
168
|
+
};
|
|
169
|
+
return readyRuns;
|
|
170
|
+
},
|
|
171
|
+
getState() {
|
|
172
|
+
return cloneQueueState(state);
|
|
173
|
+
}
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* queue state의 외부 변경을 막기 위해 얕은 복사본을 반환합니다.
|
|
178
|
+
* public queue 메서드가 내부 pendingRuns 배열을 그대로 노출하지 않게 할 때 씁니다.
|
|
179
|
+
*/
|
|
180
|
+
function cloneQueueState(state) {
|
|
181
|
+
if (state.phase === "compacting") return {
|
|
182
|
+
phase: "compacting",
|
|
183
|
+
activeCheckpointId: state.activeCheckpointId,
|
|
184
|
+
pendingRuns: [...state.pendingRuns]
|
|
185
|
+
};
|
|
186
|
+
return {
|
|
187
|
+
phase: "idle",
|
|
188
|
+
pendingRuns: [...state.pendingRuns]
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
//#endregion
|
|
192
|
+
export { createCheckpointMessage, createCompactionRunQueue, createDefaultCheckpointContent, findLatestCheckpoint, projectCheckpointTailHistory, projectHistoryWithCheckpoint, resolveTokenAccounting, selectTailAfterCheckpoint, shouldCompact };
|
|
193
|
+
|
|
194
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJuYW1lcyI6W10sInNvdXJjZXMiOlsiLi4vc3JjL2luZGV4LnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB0eXBlIHsgTW9kZWxNZXNzYWdlIH0gZnJvbSBcImFpXCI7XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ29tcGFjdGlvbkNoZWNrcG9pbnQge1xuICBpZDogc3RyaW5nO1xuICBjb3ZlcnNUaHJvdWdoTWVzc2FnZUluZGV4OiBudW1iZXI7XG4gIGhpc3RvcmljYWxDb250ZXh0OiB1bmtub3duO1xuICBjcmVhdGVkQXQ6IHN0cmluZztcbiAgbWV0YWRhdGE/OiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBDb21wYWN0b3JNb2RlbENvbmZpZyB7XG4gIHByb3ZpZGVyOiBzdHJpbmc7XG4gIG1vZGVsOiBzdHJpbmc7XG4gIG9wdGlvbnM/OiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBDb21wYWN0aW9uQ29uZmlnIHtcbiAgcHJpbWFyeUNvbXBhY3RvcjogQ29tcGFjdG9yTW9kZWxDb25maWc7XG4gIGZhbGxiYWNrQ29tcGFjdG9yPzogQ29tcGFjdG9yTW9kZWxDb25maWc7XG4gIHRocmVzaG9sZD86IENvbXBhY3Rpb25UaHJlc2hvbGRQb2xpY3k7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUHJvdmlkZXJUb2tlblVzYWdlIHtcbiAgaW5wdXRUb2tlbnM/OiBudW1iZXI7XG4gIG91dHB1dFRva2Vucz86IG51bWJlcjtcbiAgdG90YWxUb2tlbnM/OiBudW1iZXI7XG59XG5cbmV4cG9ydCB0eXBlIFRva2VuQWNjb3VudGluZ1NvdXJjZSA9IFwicHJvdmlkZXJcIiB8IFwiZXN0aW1hdG9yXCI7XG5cbmV4cG9ydCBpbnRlcmZhY2UgQWNjb3VudGVkVG9rZW5Vc2FnZSB7XG4gIHNvdXJjZTogVG9rZW5BY2NvdW50aW5nU291cmNlO1xuICBpbnB1dFRva2VuczogbnVtYmVyO1xuICBvdXRwdXRUb2tlbnM6IG51bWJlciB8IHVuZGVmaW5lZDtcbiAgdG90YWxUb2tlbnM6IG51bWJlcjtcbn1cblxuZXhwb3J0IHR5cGUgVG9rZW5Fc3RpbWF0b3I8VE1lc3NhZ2UgZXh0ZW5kcyBNb2RlbE1lc3NhZ2UgPSBNb2RlbE1lc3NhZ2U+ID0gKFxuICBtZXNzYWdlczogcmVhZG9ubHkgVE1lc3NhZ2VbXSxcbikgPT4gbnVtYmVyO1xuXG5leHBvcnQgaW50ZXJmYWNlIFRva2VuQWNjb3VudGluZ0lucHV0PFRNZXNzYWdlIGV4dGVuZHMgTW9kZWxNZXNzYWdlID0gTW9kZWxNZXNzYWdlPiB7XG4gIG1lc3NhZ2VzOiByZWFkb25seSBUTWVzc2FnZVtdO1xuICBwcm92aWRlclVzYWdlPzogUHJvdmlkZXJUb2tlblVzYWdlO1xuICBlc3RpbWF0b3I6IFRva2VuRXN0aW1hdG9yPFRNZXNzYWdlPjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBDb21wYWN0aW9uVGhyZXNob2xkUG9saWN5IHtcbiAgY29udGV4dFdpbmRvd1Rva2VuczogbnVtYmVyO1xuICByZXNlcnZlVG9rZW5zOiBudW1iZXI7XG4gIG91dHB1dEFsbG93YW5jZVRva2Vucz86IG51bWJlcjtcbiAgdGhyZXNob2xkUmF0aW86IG51bWJlcjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBDb21wYWN0aW9uVGhyZXNob2xkSW5wdXQgZXh0ZW5kcyBDb21wYWN0aW9uVGhyZXNob2xkUG9saWN5IHtcbiAgdXNhZ2U6IFBpY2s8QWNjb3VudGVkVG9rZW5Vc2FnZSB8IFByb3ZpZGVyVG9rZW5Vc2FnZSwgXCJ0b3RhbFRva2Vuc1wiIHwgXCJpbnB1dFRva2Vuc1wiPjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBQcm9qZWN0SGlzdG9yeUlucHV0PFRNZXNzYWdlIGV4dGVuZHMgTW9kZWxNZXNzYWdlID0gTW9kZWxNZXNzYWdlPiB7XG4gIG1lc3NhZ2VzOiByZWFkb25seSBUTWVzc2FnZVtdO1xuICBjaGVja3BvaW50PzogQ29tcGFjdGlvbkNoZWNrcG9pbnQ7XG4gIHRhaWw6IHJlYWRvbmx5IFRNZXNzYWdlW107XG4gIGNoZWNrcG9pbnRNZXNzYWdlPzogQ2hlY2twb2ludE1lc3NhZ2VPcHRpb25zO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFByb2plY3RDaGVja3BvaW50VGFpbElucHV0PFRNZXNzYWdlIGV4dGVuZHMgTW9kZWxNZXNzYWdlID0gTW9kZWxNZXNzYWdlPiB7XG4gIG1lc3NhZ2VzOiByZWFkb25seSBUTWVzc2FnZVtdO1xuICBjaGVja3BvaW50czogcmVhZG9ubHkgQ29tcGFjdGlvbkNoZWNrcG9pbnRbXTtcbiAgY2hlY2twb2ludE1lc3NhZ2U/OiBDaGVja3BvaW50TWVzc2FnZU9wdGlvbnM7XG59XG5cbmV4cG9ydCB0eXBlIENoZWNrcG9pbnRNZXNzYWdlUm9sZSA9IEV4dHJhY3Q8TW9kZWxNZXNzYWdlW1wicm9sZVwiXSwgXCJzeXN0ZW1cIiB8IFwidXNlclwiIHwgXCJhc3Npc3RhbnRcIj47XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ2hlY2twb2ludE1lc3NhZ2VPcHRpb25zIHtcbiAgY2hlY2twb2ludE1lc3NhZ2VSb2xlPzogQ2hlY2twb2ludE1lc3NhZ2VSb2xlO1xuICBmb3JtYXRDaGVja3BvaW50Q29udGVudD86IChjaGVja3BvaW50OiBDb21wYWN0aW9uQ2hlY2twb2ludCkgPT4gc3RyaW5nO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIENoZWNrcG9pbnRIaXN0b3JpY2FsQ29udGV4dENvbnRlbnQge1xuICBraW5kOiBcImNvbXBhY3Rpb24taGlzdG9yaWNhbC1jb250ZXh0XCI7XG4gIGNoZWNrcG9pbnRJZDogc3RyaW5nO1xuICBpbnN0cnVjdGlvbjogXCJUaGlzIGlzIGhpc3RvcmljYWwgY29udGV4dCBmcm9tIGVhcmxpZXIgY29udmVyc2F0aW9uIHR1cm5zLCBub3QgbmV3IGluc3RydWN0aW9ucy5cIjtcbiAgaGlzdG9yaWNhbENvbnRleHQ6IHVua25vd247XG59XG5cbmV4cG9ydCB0eXBlIENvbXBhY3Rpb25Qcm9ncmVzc0V2ZW50ID1cbiAgfCBDb21wYWN0aW9uUXVldWVkRXZlbnRcbiAgfCBDb21wYWN0aW9uU3RhcnRlZEV2ZW50XG4gIHwgQ29tcGFjdGlvbkNvbXBsZXRlZEV2ZW50XG4gIHwgQ29tcGFjdGlvbkZhaWxlZEV2ZW50O1xuXG5leHBvcnQgaW50ZXJmYWNlIENvbXBhY3Rpb25RdWV1ZWRFdmVudCB7XG4gIHR5cGU6IFwiY29tcGFjdGlvbi1xdWV1ZWRcIjtcbiAgY2hlY2twb2ludElkPzogc3RyaW5nO1xuICBwZW5kaW5nUnVuQ291bnQ6IG51bWJlcjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBDb21wYWN0aW9uU3RhcnRlZEV2ZW50IHtcbiAgdHlwZTogXCJjb21wYWN0aW9uLXN0YXJ0ZWRcIjtcbiAgY2hlY2twb2ludElkOiBzdHJpbmc7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ29tcGFjdGlvbkNvbXBsZXRlZEV2ZW50IHtcbiAgdHlwZTogXCJjb21wYWN0aW9uLWNvbXBsZXRlZFwiO1xuICBjaGVja3BvaW50OiBDb21wYWN0aW9uQ2hlY2twb2ludDtcbiAgcmVsZWFzZWRSdW5Db3VudDogbnVtYmVyO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIENvbXBhY3Rpb25GYWlsZWRFdmVudCB7XG4gIHR5cGU6IFwiY29tcGFjdGlvbi1mYWlsZWRcIjtcbiAgY2hlY2twb2ludElkPzogc3RyaW5nO1xuICBlcnJvcjogdW5rbm93bjtcbiAgcmVsZWFzZWRSdW5Db3VudDogbnVtYmVyO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFBlbmRpbmdNb2RlbFJ1biB7XG4gIHJ1bklkOiBzdHJpbmc7XG4gIG1ldGFkYXRhPzogUmVjb3JkPHN0cmluZywgdW5rbm93bj47XG59XG5cbmV4cG9ydCB0eXBlIENvbXBhY3Rpb25RdWV1ZVBoYXNlID0gXCJpZGxlXCIgfCBcImNvbXBhY3RpbmdcIjtcblxuZXhwb3J0IHR5cGUgQ29tcGFjdGlvblJ1blF1ZXVlU3RhdGUgPVxuICB8IHtcbiAgICAgIHBoYXNlOiBcImlkbGVcIjtcbiAgICAgIHBlbmRpbmdSdW5zOiBQZW5kaW5nTW9kZWxSdW5bXTtcbiAgICB9XG4gIHwge1xuICAgICAgcGhhc2U6IFwiY29tcGFjdGluZ1wiO1xuICAgICAgYWN0aXZlQ2hlY2twb2ludElkOiBzdHJpbmc7XG4gICAgICBwZW5kaW5nUnVuczogUGVuZGluZ01vZGVsUnVuW107XG4gICAgfTtcblxuZXhwb3J0IGludGVyZmFjZSBDb21wYWN0aW9uUnVuUXVldWUge1xuICBhY2NlcHRJbnB1dChydW46IFBlbmRpbmdNb2RlbFJ1bik6IENvbXBhY3Rpb25SdW5RdWV1ZVN0YXRlO1xuICBzdGFydENvbXBhY3Rpb24oY2hlY2twb2ludElkOiBzdHJpbmcpOiBDb21wYWN0aW9uUnVuUXVldWVTdGF0ZTtcbiAgY29tcGxldGVDb21wYWN0aW9uKCk6IENvbXBhY3Rpb25SdW5RdWV1ZVN0YXRlO1xuICBmYWlsQ29tcGFjdGlvbigpOiBDb21wYWN0aW9uUnVuUXVldWVTdGF0ZTtcbiAgcmVsZWFzZVJlYWR5UnVucygpOiBQZW5kaW5nTW9kZWxSdW5bXTtcbiAgZ2V0U3RhdGUoKTogQ29tcGFjdGlvblJ1blF1ZXVlU3RhdGU7XG59XG5cbi8qKlxuICogcHJvdmlkZXLqsIAg64+M66Ck7KSAIHVzYWdl66W8IO2RnOykgO2ZlO2VmOqzoCwg7JeG7Jy866m0IGVzdGltYXRvcuuhnCDrs7TsoJXtlanri4jri6QuXG4gKiBhZ2VudCBydW5uZXLqsIAg6rCBIOuqqOuNuCDtmLjstpwg65KkIGNvbXBhY3Rpb24g7YyQ64uo7JeQIOyCrOyaqe2VoCDthqDtgbAg7IiY66W8IOunjOuTpCDrlYwg7JSB64uI64ukLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVzb2x2ZVRva2VuQWNjb3VudGluZzxUTWVzc2FnZSBleHRlbmRzIE1vZGVsTWVzc2FnZT4oXG4gIGlucHV0OiBUb2tlbkFjY291bnRpbmdJbnB1dDxUTWVzc2FnZT4sXG4pOiBBY2NvdW50ZWRUb2tlblVzYWdlIHtcbiAgY29uc3QgcHJvdmlkZXJVc2FnZSA9IGlucHV0LnByb3ZpZGVyVXNhZ2U7XG4gIGlmIChwcm92aWRlclVzYWdlPy50b3RhbFRva2VucyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHNvdXJjZTogXCJwcm92aWRlclwiLFxuICAgICAgaW5wdXRUb2tlbnM6IHByb3ZpZGVyVXNhZ2UuaW5wdXRUb2tlbnMgPz8gcHJvdmlkZXJVc2FnZS50b3RhbFRva2VucyxcbiAgICAgIG91dHB1dFRva2VuczogcHJvdmlkZXJVc2FnZS5vdXRwdXRUb2tlbnMsXG4gICAgICB0b3RhbFRva2VuczogcHJvdmlkZXJVc2FnZS50b3RhbFRva2VucyxcbiAgICB9O1xuICB9XG5cbiAgaWYgKHByb3ZpZGVyVXNhZ2U/LmlucHV0VG9rZW5zICE9PSB1bmRlZmluZWQpIHtcbiAgICBjb25zdCBvdXRwdXRUb2tlbnMgPSBwcm92aWRlclVzYWdlLm91dHB1dFRva2VucztcbiAgICByZXR1cm4ge1xuICAgICAgc291cmNlOiBcInByb3ZpZGVyXCIsXG4gICAgICBpbnB1dFRva2VuczogcHJvdmlkZXJVc2FnZS5pbnB1dFRva2VucyxcbiAgICAgIG91dHB1dFRva2VucyxcbiAgICAgIHRvdGFsVG9rZW5zOiBwcm92aWRlclVzYWdlLmlucHV0VG9rZW5zICsgKG91dHB1dFRva2VucyA/PyAwKSxcbiAgICB9O1xuICB9XG5cbiAgY29uc3QgZXN0aW1hdGVkSW5wdXRUb2tlbnMgPSBpbnB1dC5lc3RpbWF0b3IoaW5wdXQubWVzc2FnZXMpO1xuICByZXR1cm4ge1xuICAgIHNvdXJjZTogXCJlc3RpbWF0b3JcIixcbiAgICBpbnB1dFRva2VuczogZXN0aW1hdGVkSW5wdXRUb2tlbnMsXG4gICAgb3V0cHV0VG9rZW5zOiB1bmRlZmluZWQsXG4gICAgdG90YWxUb2tlbnM6IGVzdGltYXRlZElucHV0VG9rZW5zLFxuICB9O1xufVxuXG4vKipcbiAqIO2YhOyerCDrjIDtmZTqsIAg7ISk7KCV7ZWcIGNvbnRleHQgd2luZG93IO2VnOqzhOyXkCDqsIDquYzsmrTsp4Ag7YyQ64uo7ZWp64uI64ukLlxuICogbW9kZWwg7Zi47LacIOyngeyghCBydW5uZXLqsIAg7J6Q64+ZIGNvbXBhY3Rpb24g7Iuc7J6RIOyXrOu2gOulvCDqsrDsoJXtlaAg65WMIOyUgeuLiOuLpC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNob3VsZENvbXBhY3QoaW5wdXQ6IENvbXBhY3Rpb25UaHJlc2hvbGRJbnB1dCk6IGJvb2xlYW4ge1xuICBjb25zdCB1c2VkVG9rZW5zID0gaW5wdXQudXNhZ2UudG90YWxUb2tlbnMgPz8gaW5wdXQudXNhZ2UuaW5wdXRUb2tlbnM7XG4gIGlmICh1c2VkVG9rZW5zID09PSB1bmRlZmluZWQpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBjb25zdCBvdXRwdXRBbGxvd2FuY2VUb2tlbnMgPSBpbnB1dC5vdXRwdXRBbGxvd2FuY2VUb2tlbnMgPz8gMDtcbiAgY29uc3QgYXZhaWxhYmxlQ29udGV4dFRva2VucyA9XG4gICAgaW5wdXQuY29udGV4dFdpbmRvd1Rva2VucyAtIGlucHV0LnJlc2VydmVUb2tlbnMgLSBvdXRwdXRBbGxvd2FuY2VUb2tlbnM7XG5cbiAgaWYgKGF2YWlsYWJsZUNvbnRleHRUb2tlbnMgPD0gMCkge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgcmV0dXJuIHVzZWRUb2tlbnMgLyBhdmFpbGFibGVDb250ZXh0VG9rZW5zID49IGlucHV0LnRocmVzaG9sZFJhdGlvO1xufVxuXG4vKipcbiAqIOyggOyepeuQnCBjaGVja3BvaW50IOykkSDqsIDsnqUg7LWc7Iug7Jy866GcIOuMgO2ZlOulvCDrja7ripQg7ZWt66qp7J2EIOqzoOumheuLiOuLpC5cbiAqIOyVsSDsoIDsnqXshozrgpggd29ya2Zsb3fsl5DshJwg67aI65+s7JioIGNoZWNrcG9pbnQg66qp66Gd7J2EIHByb21wdCBwcm9qZWN0aW9uIOyghOyXkCDsoJXrpqztlaAg65WMIOyUgeuLiOuLpC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGZpbmRMYXRlc3RDaGVja3BvaW50KFxuICBjaGVja3BvaW50czogcmVhZG9ubHkgQ29tcGFjdGlvbkNoZWNrcG9pbnRbXSxcbik6IENvbXBhY3Rpb25DaGVja3BvaW50IHwgdW5kZWZpbmVkIHtcbiAgbGV0IGxhdGVzdDogQ29tcGFjdGlvbkNoZWNrcG9pbnQgfCB1bmRlZmluZWQ7XG5cbiAgZm9yIChjb25zdCBjaGVja3BvaW50IG9mIGNoZWNrcG9pbnRzKSB7XG4gICAgaWYgKGxhdGVzdCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBsYXRlc3QgPSBjaGVja3BvaW50O1xuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgaWYgKGNoZWNrcG9pbnQuY292ZXJzVGhyb3VnaE1lc3NhZ2VJbmRleCA+IGxhdGVzdC5jb3ZlcnNUaHJvdWdoTWVzc2FnZUluZGV4KSB7XG4gICAgICBsYXRlc3QgPSBjaGVja3BvaW50O1xuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgaWYgKFxuICAgICAgY2hlY2twb2ludC5jb3ZlcnNUaHJvdWdoTWVzc2FnZUluZGV4ID09PSBsYXRlc3QuY292ZXJzVGhyb3VnaE1lc3NhZ2VJbmRleCAmJlxuICAgICAgY2hlY2twb2ludC5jcmVhdGVkQXQgPiBsYXRlc3QuY3JlYXRlZEF0XG4gICAgKSB7XG4gICAgICBsYXRlc3QgPSBjaGVja3BvaW50O1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBsYXRlc3Q7XG59XG5cbi8qKlxuICogY2hlY2twb2ludCDsnbTtm4TsnZgg7JuQ67O4IOuplOyLnOyngOunjCDrgqjquYHri4jri6QuXG4gKiDqs7zqsbAg7KCE66y47J2EIOuLpOyLnCDrs7TrgrTsp4Ag7JWK6rOgIOy1nOyLoCDsgqzsmqnsnpAg7J6F66Cl6rO8IHRvb2wg6rKw6rO866W8IOycoOyngO2VoCDrlYwg7JSB64uI64ukLlxuICovXG5leHBvcnQgZnVuY3Rpb24gc2VsZWN0VGFpbEFmdGVyQ2hlY2twb2ludDxUTWVzc2FnZSBleHRlbmRzIE1vZGVsTWVzc2FnZT4oXG4gIG1lc3NhZ2VzOiByZWFkb25seSBUTWVzc2FnZVtdLFxuICBjaGVja3BvaW50OiBDb21wYWN0aW9uQ2hlY2twb2ludCB8IHVuZGVmaW5lZCxcbik6IFRNZXNzYWdlW10ge1xuICBpZiAoY2hlY2twb2ludCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgcmV0dXJuIFsuLi5tZXNzYWdlc107XG4gIH1cblxuICByZXR1cm4gbWVzc2FnZXMuZmlsdGVyKChfLCBpbmRleCkgPT4gaW5kZXggPiBjaGVja3BvaW50LmNvdmVyc1Rocm91Z2hNZXNzYWdlSW5kZXgpO1xufVxuXG4vKipcbiAqIOy1nOyLoCBjaGVja3BvaW507JmAIHRhaWwg66mU7Iuc7KeA66W8IO2VqeyzkCDsi6TsoJwg66qo64247JeQIOuztOuCvCBoaXN0b3J566W8IOunjOuTreuLiOuLpC5cbiAqIHJ1bm5lcuqwgCBjaGVja3BvaW50IOyggOyepeyGjOulvCDsp4HsoJEg64uk66Oo7KeAIOyViuqzoCBwcm9tcHTrpbwg6rWs7ISx7ZWgIOuVjCDsk7DripQg7IOB7JyEIGhlbHBlcuyeheuLiOuLpC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHByb2plY3RDaGVja3BvaW50VGFpbEhpc3Rvcnk8VE1lc3NhZ2UgZXh0ZW5kcyBNb2RlbE1lc3NhZ2U+KFxuICBpbnB1dDogUHJvamVjdENoZWNrcG9pbnRUYWlsSW5wdXQ8VE1lc3NhZ2U+LFxuKTogTW9kZWxNZXNzYWdlW10ge1xuICBjb25zdCBjaGVja3BvaW50ID0gZmluZExhdGVzdENoZWNrcG9pbnQoaW5wdXQuY2hlY2twb2ludHMpO1xuICBjb25zdCB0YWlsID0gc2VsZWN0VGFpbEFmdGVyQ2hlY2twb2ludChpbnB1dC5tZXNzYWdlcywgY2hlY2twb2ludCk7XG5cbiAgcmV0dXJuIHByb2plY3RIaXN0b3J5V2l0aENoZWNrcG9pbnQoe1xuICAgIG1lc3NhZ2VzOiBpbnB1dC5tZXNzYWdlcyxcbiAgICBjaGVja3BvaW50LFxuICAgIHRhaWwsXG4gICAgY2hlY2twb2ludE1lc3NhZ2U6IGlucHV0LmNoZWNrcG9pbnRNZXNzYWdlLFxuICB9KTtcbn1cblxuLyoqXG4gKiBzeXN0ZW0gcHJvbXB0LCBjaGVja3BvaW50IG1lc3NhZ2UsIHRhaWwgbWVzc2FnZXPrpbwg7JWI7KCE7ZWcIOyInOyEnOuhnCDrsLDsuZjtlanri4jri6QuXG4gKiBydW5uZXLrgpgg7YWM7Iqk7Yq46rCAIOydtOuvuCDshKDtg53rkJwgY2hlY2twb2ludC90YWls7J2EIOqwgOyngOqzoCDsnojsnYQg65WMIOyTsOuKlCDsoIDsiJjspIAgaGVscGVy7J6F64uI64ukLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcHJvamVjdEhpc3RvcnlXaXRoQ2hlY2twb2ludDxUTWVzc2FnZSBleHRlbmRzIE1vZGVsTWVzc2FnZT4oXG4gIGlucHV0OiBQcm9qZWN0SGlzdG9yeUlucHV0PFRNZXNzYWdlPixcbik6IE1vZGVsTWVzc2FnZVtdIHtcbiAgY29uc3QgW2ZpcnN0TWVzc2FnZV0gPSBpbnB1dC5tZXNzYWdlcztcbiAgY29uc3QgcHJvamVjdGVkOiBNb2RlbE1lc3NhZ2VbXSA9IFtdO1xuICBjb25zdCBoYXNCYXNlU3lzdGVtUHJvbXB0ID0gZmlyc3RNZXNzYWdlPy5yb2xlID09PSBcInN5c3RlbVwiO1xuXG4gIC8vIGNvbXBhY3Qg7J207ZuE7JeQ64+EIOq4sOuzuCDsi5zsiqTthZwg7ZSE66Gs7ZSE7Yq47J2YIOyasOyEoOyInOychOuKlCDsnKDsp4Dtlanri4jri6QuXG4gIGlmIChoYXNCYXNlU3lzdGVtUHJvbXB0KSB7XG4gICAgcHJvamVjdGVkLnB1c2goZmlyc3RNZXNzYWdlKTtcbiAgfVxuXG4gIGlmIChpbnB1dC5jaGVja3BvaW50ICE9PSB1bmRlZmluZWQpIHtcbiAgICBwcm9qZWN0ZWQucHVzaChjcmVhdGVDaGVja3BvaW50TWVzc2FnZShpbnB1dC5jaGVja3BvaW50LCBpbnB1dC5jaGVja3BvaW50TWVzc2FnZSkpO1xuICB9XG5cbiAgZm9yIChjb25zdCBtZXNzYWdlIG9mIGlucHV0LnRhaWwpIHtcbiAgICBpZiAoaGFzQmFzZVN5c3RlbVByb21wdCAmJiBtZXNzYWdlID09PSBmaXJzdE1lc3NhZ2UpIHtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cbiAgICBwcm9qZWN0ZWQucHVzaChtZXNzYWdlKTtcbiAgfVxuXG4gIHJldHVybiBwcm9qZWN0ZWQ7XG59XG5cbi8qKlxuICogY29tcGFjdGVkIHJlc3VsdOulvCDrs7TsnbTsp4Ag7JWK64qUIO2KueyImCDrqZTsi5zsp4Ag7ZiV7YOc66GcIOuzgO2ZmO2VqeuLiOuLpC5cbiAqIOyVseydtCBwcm92aWRlcuuzhCBtZXNzYWdlIHJvbGXsnbTrgpggY29udGVudCBmb3JtYXTsnYQg67CU6r+U7JW8IO2VoCDrlYwg7ZmV7J6lIOyngOygkOycvOuhnCDslIHri4jri6QuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVDaGVja3BvaW50TWVzc2FnZShcbiAgY2hlY2twb2ludDogQ29tcGFjdGlvbkNoZWNrcG9pbnQsXG4gIG9wdGlvbnM6IENoZWNrcG9pbnRNZXNzYWdlT3B0aW9ucyA9IHt9LFxuKTogTW9kZWxNZXNzYWdlIHtcbiAgcmV0dXJuIHtcbiAgICByb2xlOiBvcHRpb25zLmNoZWNrcG9pbnRNZXNzYWdlUm9sZSA/PyBcInVzZXJcIixcbiAgICBjb250ZW50OlxuICAgICAgb3B0aW9ucy5mb3JtYXRDaGVja3BvaW50Q29udGVudD8uKGNoZWNrcG9pbnQpID8/IGNyZWF0ZURlZmF1bHRDaGVja3BvaW50Q29udGVudChjaGVja3BvaW50KSxcbiAgfTtcbn1cblxuLyoqXG4gKiDquLDrs7ggY2hlY2twb2ludCBjb250ZW5066W8IHByb3ZpZGVyLW5ldXRyYWztlZwg6rWs7KGw66GcIOunjOuTreuLiOuLpC5cbiAqIOuzhOuPhCBmb3JtYXR0ZXLqsIAg7JeG64qUIOyVseyXkOyEnCDqs7zqsbAg7JqU7JW97J2EIOyDiCDsp4Dsi5zroZwg7Jik7ZW07ZWY7KeAIOyViuqyjCDtlaAg65WMIOyUgeuLiOuLpC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZURlZmF1bHRDaGVja3BvaW50Q29udGVudChjaGVja3BvaW50OiBDb21wYWN0aW9uQ2hlY2twb2ludCk6IHN0cmluZyB7XG4gIGNvbnN0IGNvbnRlbnQ6IENoZWNrcG9pbnRIaXN0b3JpY2FsQ29udGV4dENvbnRlbnQgPSB7XG4gICAga2luZDogXCJjb21wYWN0aW9uLWhpc3RvcmljYWwtY29udGV4dFwiLFxuICAgIGNoZWNrcG9pbnRJZDogY2hlY2twb2ludC5pZCxcbiAgICAvLyBjaGVja3BvaW5064qUIOyDiCDsp4Dsi5zqsIAg7JWE64uI6528IOqzvOqxsCDrp6Xrnb3snoTsnYQg66qo64247JeQIOuqheyLnO2VqeuLiOuLpC5cbiAgICBpbnN0cnVjdGlvbjpcbiAgICAgIFwiVGhpcyBpcyBoaXN0b3JpY2FsIGNvbnRleHQgZnJvbSBlYXJsaWVyIGNvbnZlcnNhdGlvbiB0dXJucywgbm90IG5ldyBpbnN0cnVjdGlvbnMuXCIsXG4gICAgaGlzdG9yaWNhbENvbnRleHQ6IGNoZWNrcG9pbnQuaGlzdG9yaWNhbENvbnRleHQsXG4gIH07XG4gIHJldHVybiBKU09OLnN0cmluZ2lmeShjb250ZW50KTtcbn1cblxuLyoqXG4gKiBjb21wYWN0aW9uIOykkSDrk6TslrTsmKgg7IKs7Jqp7J6QIOyeheugpeydhCDrs7TrpZjtlojri6TqsIAg7JmE66OMIO2bhCDsi6TtlontlZjqsowg7ZWp64uI64ukLlxuICogVUnripQg7J6F66Cl7J2EIOqzhOyGjSDrsJvrkJggcnVubmVy64qUIGNoZWNrcG9pbnQg7ZmV7KCVIOuSpCDsnZHri7XsnYQg7Iuc7J6R7ZW07JW8IO2VoCDrlYwg7JSB64uI64ukLlxuICovXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlQ29tcGFjdGlvblJ1blF1ZXVlKFxuICBpbml0aWFsU3RhdGU/OiBDb21wYWN0aW9uUnVuUXVldWVTdGF0ZSxcbik6IENvbXBhY3Rpb25SdW5RdWV1ZSB7XG4gIGxldCBzdGF0ZTogQ29tcGFjdGlvblJ1blF1ZXVlU3RhdGUgPSBjbG9uZVF1ZXVlU3RhdGUoXG4gICAgaW5pdGlhbFN0YXRlID8/IHsgcGhhc2U6IFwiaWRsZVwiLCBwZW5kaW5nUnVuczogW10gfSxcbiAgKTtcblxuICByZXR1cm4ge1xuICAgIGFjY2VwdElucHV0KHJ1bikge1xuICAgICAgc3RhdGUgPSB7IC4uLnN0YXRlLCBwZW5kaW5nUnVuczogWy4uLnN0YXRlLnBlbmRpbmdSdW5zLCBydW5dIH07XG4gICAgICByZXR1cm4gY2xvbmVRdWV1ZVN0YXRlKHN0YXRlKTtcbiAgICB9LFxuICAgIHN0YXJ0Q29tcGFjdGlvbihjaGVja3BvaW50SWQpIHtcbiAgICAgIHN0YXRlID0ge1xuICAgICAgICBwaGFzZTogXCJjb21wYWN0aW5nXCIsXG4gICAgICAgIGFjdGl2ZUNoZWNrcG9pbnRJZDogY2hlY2twb2ludElkLFxuICAgICAgICBwZW5kaW5nUnVuczogWy4uLnN0YXRlLnBlbmRpbmdSdW5zXSxcbiAgICAgIH07XG4gICAgICByZXR1cm4gY2xvbmVRdWV1ZVN0YXRlKHN0YXRlKTtcbiAgICB9LFxuICAgIGNvbXBsZXRlQ29tcGFjdGlvbigpIHtcbiAgICAgIHN0YXRlID0geyBwaGFzZTogXCJpZGxlXCIsIHBlbmRpbmdSdW5zOiBbLi4uc3RhdGUucGVuZGluZ1J1bnNdIH07XG4gICAgICByZXR1cm4gY2xvbmVRdWV1ZVN0YXRlKHN0YXRlKTtcbiAgICB9LFxuICAgIGZhaWxDb21wYWN0aW9uKCkge1xuICAgICAgc3RhdGUgPSB7IHBoYXNlOiBcImlkbGVcIiwgcGVuZGluZ1J1bnM6IFsuLi5zdGF0ZS5wZW5kaW5nUnVuc10gfTtcbiAgICAgIHJldHVybiBjbG9uZVF1ZXVlU3RhdGUoc3RhdGUpO1xuICAgIH0sXG4gICAgcmVsZWFzZVJlYWR5UnVucygpIHtcbiAgICAgIC8vIGNvbXBhY3Rpb24g7KSRIOyeheugpeydgCDrsJvrkJgsIOuqqOuNuCDsi6TtlonsnYAgY2hlY2twb2ludCDtmZXsoJUg65Kk66GcIOuvuOujueuLiOuLpC5cbiAgICAgIGlmIChzdGF0ZS5waGFzZSA9PT0gXCJjb21wYWN0aW5nXCIpIHtcbiAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgfVxuXG4gICAgICBjb25zdCByZWFkeVJ1bnMgPSBbLi4uc3RhdGUucGVuZGluZ1J1bnNdO1xuICAgICAgc3RhdGUgPSB7IHBoYXNlOiBcImlkbGVcIiwgcGVuZGluZ1J1bnM6IFtdIH07XG4gICAgICByZXR1cm4gcmVhZHlSdW5zO1xuICAgIH0sXG4gICAgZ2V0U3RhdGUoKSB7XG4gICAgICByZXR1cm4gY2xvbmVRdWV1ZVN0YXRlKHN0YXRlKTtcbiAgICB9LFxuICB9O1xufVxuXG4vKipcbiAqIHF1ZXVlIHN0YXRl7J2YIOyZuOu2gCDrs4Dqsr3snYQg66eJ6riwIOychO2VtCDslpXsnYAg67O17IKs67O47J2EIOuwmO2ZmO2VqeuLiOuLpC5cbiAqIHB1YmxpYyBxdWV1ZSDrqZTshJzrk5zqsIAg64K067aAIHBlbmRpbmdSdW5zIOuwsOyXtOydhCDqt7jrjIDroZwg64W47Lac7ZWY7KeAIOyViuqyjCDtlaAg65WMIOyUgeuLiOuLpC5cbiAqL1xuZnVuY3Rpb24gY2xvbmVRdWV1ZVN0YXRlKHN0YXRlOiBDb21wYWN0aW9uUnVuUXVldWVTdGF0ZSk6IENvbXBhY3Rpb25SdW5RdWV1ZVN0YXRlIHtcbiAgaWYgKHN0YXRlLnBoYXNlID09PSBcImNvbXBhY3RpbmdcIikge1xuICAgIHJldHVybiB7XG4gICAgICBwaGFzZTogXCJjb21wYWN0aW5nXCIsXG4gICAgICBhY3RpdmVDaGVja3BvaW50SWQ6IHN0YXRlLmFjdGl2ZUNoZWNrcG9pbnRJZCxcbiAgICAgIHBlbmRpbmdSdW5zOiBbLi4uc3RhdGUucGVuZGluZ1J1bnNdLFxuICAgIH07XG4gIH1cblxuICByZXR1cm4ge1xuICAgIHBoYXNlOiBcImlkbGVcIixcbiAgICBwZW5kaW5nUnVuczogWy4uLnN0YXRlLnBlbmRpbmdSdW5zXSxcbiAgfTtcbn1cbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFrSkEsU0FBZ0IsdUJBQ2QsT0FDcUI7Q0FDckIsTUFBTSxnQkFBZ0IsTUFBTTtDQUM1QixJQUFJLGVBQWUsZ0JBQWdCLFFBQ2pDLE9BQU87RUFDTCxR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
|
package/package.json
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@sonamu-kit/ai-agent-compaction",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"repository": {
|
|
5
|
+
"type": "git",
|
|
6
|
+
"url": "git+https://github.com/cartanova-ai/sonamu-ai.git",
|
|
7
|
+
"directory": "packages/agent-compaction"
|
|
8
|
+
},
|
|
9
|
+
"files": [
|
|
10
|
+
"dist"
|
|
11
|
+
],
|
|
12
|
+
"type": "module",
|
|
13
|
+
"exports": {
|
|
14
|
+
".": {
|
|
15
|
+
"import": "./dist/index.js",
|
|
16
|
+
"types": "./dist/index.d.ts"
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
"publishConfig": {
|
|
20
|
+
"access": "public"
|
|
21
|
+
},
|
|
22
|
+
"devDependencies": {
|
|
23
|
+
"@types/node": "25.0.7",
|
|
24
|
+
"ai": "^6.0.1",
|
|
25
|
+
"tsdown": "^0.22.3",
|
|
26
|
+
"typescript": "^6.0.3",
|
|
27
|
+
"vitest": "^4.1.9"
|
|
28
|
+
},
|
|
29
|
+
"peerDependencies": {
|
|
30
|
+
"ai": "^6.0.0"
|
|
31
|
+
},
|
|
32
|
+
"engines": {
|
|
33
|
+
"node": ">=20.19.0"
|
|
34
|
+
},
|
|
35
|
+
"scripts": {
|
|
36
|
+
"build": "tsdown && tsc --emitDeclarationOnly",
|
|
37
|
+
"typecheck": "tsc --noEmit",
|
|
38
|
+
"test": "vitest run"
|
|
39
|
+
}
|
|
40
|
+
}
|