minovative-mind-cli 2.2.5 → 2.3.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/LICENSE.md +2 -0
- package/README.md +8 -8
- package/dist/commands/logout.js +1 -1
- package/dist/services/agent/slashCommands.js +53 -14
- package/dist/services/agent/toolLoop.js +4 -1
- package/dist/services/agent/types.d.ts +4 -0
- package/dist/services/agent-tools.js +55 -27
- package/dist/services/agent.d.ts +4 -0
- package/dist/services/agent.js +77 -60
- package/dist/services/ai.d.ts +1 -2
- package/dist/services/ai.js +21 -19
- package/dist/services/auth.d.ts +1 -1
- package/dist/services/auth.js +7 -28
- package/dist/services/chatHistoryService.d.ts +8 -0
- package/dist/services/contextAgent.js +18 -1
- package/dist/services/investigationComplexity.d.ts +1 -1
- package/dist/services/investigationComplexity.js +1 -1
- package/dist/services/orchestration/investigationAgent.d.ts +2 -2
- package/dist/services/orchestration/investigationAgent.js +25 -6
- package/dist/services/orchestration/orchestrator.d.ts +1 -1
- package/dist/services/orchestration/orchestrator.js +37 -18
- package/dist/services/orchestration/subAgent.d.ts +1 -1
- package/dist/services/orchestration/subAgent.js +23 -13
- package/dist/services/proxyClient.d.ts +16 -14
- package/dist/services/proxyClient.js +199 -103
- package/dist/utils/analysisRunner.js +2 -2
- package/dist/utils/config.d.ts +3 -3
- package/dist/utils/config.js +3 -3
- package/dist/utils/credentialStore.d.ts +30 -0
- package/dist/utils/credentialStore.js +540 -0
- package/dist/utils/projectStorage.js +70 -0
- package/dist/utils/systemPrompts.d.ts +3 -3
- package/dist/utils/systemPrompts.js +4 -4
- package/oclif.manifest.json +1 -1
- package/package.json +2 -1
|
@@ -40,8 +40,8 @@ export class InvestigationAgentRunner {
|
|
|
40
40
|
creditsUsed = 0;
|
|
41
41
|
inputTokens = 0;
|
|
42
42
|
outputTokens = 0;
|
|
43
|
-
/**
|
|
44
|
-
static STALL_TIMEOUT_MS =
|
|
43
|
+
/** Stall timeout for investigation agents (300s to allow for heavy vision/web tasks) */
|
|
44
|
+
static STALL_TIMEOUT_MS = 300_000;
|
|
45
45
|
constructor(agentLabel, domains, workspaceRoot, readCache, projectTree, projectType) {
|
|
46
46
|
this.agentLabel = agentLabel;
|
|
47
47
|
this.domains = domains;
|
|
@@ -51,7 +51,7 @@ export class InvestigationAgentRunner {
|
|
|
51
51
|
this.projectType = projectType;
|
|
52
52
|
let model = getGlobalActiveModel();
|
|
53
53
|
if (model === GEMINI_MODELS.AUTO)
|
|
54
|
-
model = GEMINI_MODELS.
|
|
54
|
+
model = GEMINI_MODELS.FLASH;
|
|
55
55
|
this.chat = new ProxyChatSession(model, this.buildSystemInstruction(), getContextToolDeclarations(), {
|
|
56
56
|
maxOutputTokens: MAX_OUTPUT_TOKENS,
|
|
57
57
|
temperature: 1,
|
|
@@ -114,6 +114,8 @@ export class InvestigationAgentRunner {
|
|
|
114
114
|
currentMessage += `\n\nStart investigating to find relevant files within your assigned domains.`;
|
|
115
115
|
let isFinished = false;
|
|
116
116
|
const visitedToolCalls = new Set();
|
|
117
|
+
let consecutiveDuplicates = 0;
|
|
118
|
+
const MAX_CONSECUTIVE_DUPLICATES = 3;
|
|
117
119
|
// Tool loop — mirrors the existing context agent loop in contextAgent.ts
|
|
118
120
|
while (!crashed && !abortSignal.aborted && !isFinished) {
|
|
119
121
|
this.pingHeartbeat();
|
|
@@ -144,14 +146,31 @@ export class InvestigationAgentRunner {
|
|
|
144
146
|
// Deduplicate identical tool calls
|
|
145
147
|
const callSignature = `${call.name}:${JSON.stringify(args)}`;
|
|
146
148
|
if (call.name !== 'finish_investigation' && visitedToolCalls.has(callSignature)) {
|
|
149
|
+
consecutiveDuplicates++;
|
|
150
|
+
if (consecutiveDuplicates >= MAX_CONSECUTIVE_DUPLICATES) {
|
|
151
|
+
// Force-finish: the model is stuck in a loop
|
|
152
|
+
const forceMsg = `Investigation auto-completed: the model repeated the same tool call ${MAX_CONSECUTIVE_DUPLICATES} times consecutively.`;
|
|
153
|
+
debugLog(`InvestigationAgent [${this.agentLabel}]: ${forceMsg}`);
|
|
154
|
+
if (onProgress)
|
|
155
|
+
onProgress(`[${this.agentLabel}] ${forceMsg}`);
|
|
156
|
+
if (!summary || summary === 'No relevant context found.') {
|
|
157
|
+
summary = 'Investigation was auto-completed due to repeated duplicate tool calls. Review the gathered files for context.';
|
|
158
|
+
}
|
|
159
|
+
isFinished = true;
|
|
160
|
+
success = relevantFiles.size > 0;
|
|
161
|
+
break;
|
|
162
|
+
}
|
|
147
163
|
functionResponses.push({
|
|
148
164
|
functionResponse: {
|
|
149
165
|
name: call.name,
|
|
150
|
-
response: {
|
|
151
|
-
|
|
166
|
+
response: {
|
|
167
|
+
error: `DUPLICATE CALL BLOCKED (attempt ${consecutiveDuplicates}/${MAX_CONSECUTIVE_DUPLICATES}): You already executed this exact tool call. Do NOT retry it. Use the results you already have and call finish_investigation now, or try a DIFFERENT tool call with different parameters.`,
|
|
168
|
+
},
|
|
169
|
+
},
|
|
152
170
|
});
|
|
153
171
|
continue;
|
|
154
172
|
}
|
|
173
|
+
consecutiveDuplicates = 0;
|
|
155
174
|
visitedToolCalls.add(callSignature);
|
|
156
175
|
if (call.name === 'finish_investigation') {
|
|
157
176
|
summary = args.summary || '';
|
|
@@ -345,7 +364,7 @@ export class InvestigationAgentRunner {
|
|
|
345
364
|
if (usage) {
|
|
346
365
|
const input = (usage.promptTokens || 0) + (usage.cachedTokens || 0);
|
|
347
366
|
const output = usage.candidatesTokens || 0;
|
|
348
|
-
const tokens = usage.totalTokenCount ||
|
|
367
|
+
const tokens = usage.totalTokenCount || input + output;
|
|
349
368
|
this.inputTokens += input;
|
|
350
369
|
this.outputTokens += output;
|
|
351
370
|
this.creditsUsed += tokens;
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* @fileoverview Main Orchestrator for Sub-Agent Dispatch and Coordination.
|
|
3
3
|
*
|
|
4
4
|
* The orchestrator acts as the "PM Kernel", responsible for:
|
|
5
|
-
* 1. Task Decomposition (using gemini-3.
|
|
5
|
+
* 1. Task Decomposition (using gemini-3.6-flash)
|
|
6
6
|
* 2. Graph Validation (Cycle detection via Kahn's algorithm)
|
|
7
7
|
* 3. Lock Ordering (Conflict resolution across parallel waves)
|
|
8
8
|
* 4. Parallel Dispatch (Executing waves sequentially, agents in parallel)
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* @fileoverview Main Orchestrator for Sub-Agent Dispatch and Coordination.
|
|
3
3
|
*
|
|
4
4
|
* The orchestrator acts as the "PM Kernel", responsible for:
|
|
5
|
-
* 1. Task Decomposition (using gemini-3.
|
|
5
|
+
* 1. Task Decomposition (using gemini-3.6-flash)
|
|
6
6
|
* 2. Graph Validation (Cycle detection via Kahn's algorithm)
|
|
7
7
|
* 3. Lock Ordering (Conflict resolution across parallel waves)
|
|
8
8
|
* 4. Parallel Dispatch (Executing waves sequentially, agents in parallel)
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
import * as p from '@clack/prompts';
|
|
12
12
|
import pc from 'picocolors';
|
|
13
13
|
import { ProxyChatSession, getGlobalActiveModel, compressTextUsingFlashLite } from '../ai.js';
|
|
14
|
+
import { peekTurnUsage } from '../proxyClient.js';
|
|
14
15
|
import { GEMINI_MODELS, MAX_OUTPUT_TOKENS } from '../../utils/config.js';
|
|
15
16
|
import { debugLog } from '../../utils/logger.js';
|
|
16
17
|
import { MessageBus } from './messageBus.js';
|
|
@@ -19,19 +20,22 @@ import { SubAgentRunner } from './subAgent.js';
|
|
|
19
20
|
import { validateTaskGraph, computeExecutionWaves, detectFileConflicts, resolveFileConflicts, buildCycleCorrectionPrompt, CyclicDependencyError, } from './taskGraph.js';
|
|
20
21
|
import { trackTask } from '../../utils/taskVisualizer.js';
|
|
21
22
|
// ─── Constants ───────────────────────────────────────────────────────
|
|
22
|
-
const PM_SYSTEM_INSTRUCTION =
|
|
23
|
+
const PM_SYSTEM_INSTRUCTION = `<identity>
|
|
24
|
+
You are the PM Agent (Project Manager).
|
|
23
25
|
Your job is to decompose the user's objective into a parallelizable Task Graph for sub-agents.
|
|
24
26
|
You must output ONLY raw JSON representing the TaskGraph object. Do not wrap in markdown code blocks.
|
|
27
|
+
</identity>
|
|
25
28
|
|
|
26
|
-
|
|
29
|
+
<requirements>
|
|
27
30
|
- Break the work down logically based on file isolation and dependency chains.
|
|
28
31
|
- Tasks that don't depend on each other will run in parallel.
|
|
29
32
|
- If a task depends on another, it must list its ID in "dependsOn".
|
|
30
33
|
- Do NOT create cyclic dependencies (A -> B -> A).
|
|
31
34
|
- If the entire objective is very simple and only requires modifying 1-2 files sequentially, output a graph with exactly 1 task.
|
|
32
35
|
- Ensure 'targetFiles' lists all files the task will modify.
|
|
36
|
+
</requirements>
|
|
33
37
|
|
|
34
|
-
|
|
38
|
+
<json_schema>
|
|
35
39
|
{
|
|
36
40
|
"objective": "string",
|
|
37
41
|
"tasks": [
|
|
@@ -46,7 +50,7 @@ JSON Schema:
|
|
|
46
50
|
],
|
|
47
51
|
"constraints": ["string"]
|
|
48
52
|
}
|
|
49
|
-
|
|
53
|
+
</json_schema>`;
|
|
50
54
|
// ─── Orchestrator Implementation ─────────────────────────────────────
|
|
51
55
|
export class Orchestrator {
|
|
52
56
|
workspaceRoot;
|
|
@@ -64,7 +68,7 @@ export class Orchestrator {
|
|
|
64
68
|
this.locks = new FileLockRegistry();
|
|
65
69
|
let model = getGlobalActiveModel();
|
|
66
70
|
if (model === GEMINI_MODELS.AUTO)
|
|
67
|
-
model = GEMINI_MODELS.
|
|
71
|
+
model = GEMINI_MODELS.FLASH;
|
|
68
72
|
this.pmChat = new ProxyChatSession(model, PM_SYSTEM_INSTRUCTION, [], {
|
|
69
73
|
maxOutputTokens: MAX_OUTPUT_TOKENS,
|
|
70
74
|
temperature: 0.1,
|
|
@@ -97,10 +101,12 @@ export class Orchestrator {
|
|
|
97
101
|
for (const wave of waves) {
|
|
98
102
|
if (signal.aborted)
|
|
99
103
|
break;
|
|
100
|
-
const taskDescriptions = wave.taskIds
|
|
101
|
-
|
|
104
|
+
const taskDescriptions = wave.taskIds
|
|
105
|
+
.map((taskId) => {
|
|
106
|
+
const taskDef = graph.tasks.find((t) => t.id === taskId);
|
|
102
107
|
return ` - ${pc.cyan(taskDef.id)}: ${pc.dim(taskDef.intent)}`;
|
|
103
|
-
})
|
|
108
|
+
})
|
|
109
|
+
.join('\n');
|
|
104
110
|
p.log.step(pc.magenta(`Starting Wave ${wave.depth + 1} (${wave.taskIds.length} tasks):\n${taskDescriptions}`));
|
|
105
111
|
const s = p.spinner();
|
|
106
112
|
s.start(`Executing Wave ${wave.depth + 1}...`);
|
|
@@ -116,8 +122,8 @@ export class Orchestrator {
|
|
|
116
122
|
const MAX_CONCURRENT = 2;
|
|
117
123
|
for (let i = 0; i < wave.taskIds.length; i += MAX_CONCURRENT) {
|
|
118
124
|
const chunk = wave.taskIds.slice(i, i + MAX_CONCURRENT);
|
|
119
|
-
const wavePromises = chunk.map(taskId => {
|
|
120
|
-
const taskDef = graph.tasks.find(t => t.id === taskId);
|
|
125
|
+
const wavePromises = chunk.map((taskId) => {
|
|
126
|
+
const taskDef = graph.tasks.find((t) => t.id === taskId);
|
|
121
127
|
const globalContext = `Objective:\n${objective}\n\nContext:\n${contextInjection}`;
|
|
122
128
|
agentStatuses.set(taskDef.id, 'Starting...');
|
|
123
129
|
updateSpinner();
|
|
@@ -131,7 +137,7 @@ export class Orchestrator {
|
|
|
131
137
|
}
|
|
132
138
|
s.stop(`Wave ${wave.depth + 1} execution finished.`);
|
|
133
139
|
// Post-wave evaluation
|
|
134
|
-
const failedCount = results.filter(r => !r.success).length;
|
|
140
|
+
const failedCount = results.filter((r) => !r.success).length;
|
|
135
141
|
if (failedCount > 0) {
|
|
136
142
|
p.log.warn(pc.yellow(`Wave ${wave.depth + 1} finished with ${failedCount} failure(s).`));
|
|
137
143
|
// Phase 3 implementation note: Right now, we continue and let downstream
|
|
@@ -232,28 +238,41 @@ export class Orchestrator {
|
|
|
232
238
|
let rawSummaryData = '';
|
|
233
239
|
for (const [taskId, res] of this.agentResults.entries()) {
|
|
234
240
|
totalTokens += res.creditsUsed;
|
|
235
|
-
inputTokens +=
|
|
236
|
-
outputTokens +=
|
|
241
|
+
inputTokens += res.inputTokens || 0;
|
|
242
|
+
outputTokens += res.outputTokens || 0;
|
|
237
243
|
if (!res.success)
|
|
238
244
|
failedTasks++;
|
|
239
245
|
debugLog(`Task ${taskId} summary: ${res.summary.substring(0, 100)}...`);
|
|
240
246
|
rawSummaryData += `Task: ${taskId} | Status: ${res.success ? 'Success' : 'Failed'}\nChanges:\n${res.summary}\n\n`;
|
|
241
247
|
}
|
|
242
248
|
p.log.step(pc.cyan('Orchestrator: Synthesizing final changes overview...'));
|
|
243
|
-
let finalSummary = '
|
|
249
|
+
let finalSummary = '';
|
|
244
250
|
try {
|
|
245
|
-
const
|
|
246
|
-
const
|
|
251
|
+
const payloadWithContext = `<original_request>\n${graph.objective}\n</original_request>\n\n<task_summaries>\n${rawSummaryData}\n</task_summaries>`;
|
|
252
|
+
const instruction = '<identity>\n' +
|
|
253
|
+
"You are Mino, a Senior software developer. You just delegated the user's complex request to multiple parallel sub-agents, and they have finished. " +
|
|
254
|
+
"Below is the user's original request, followed by the raw task completion summaries from the sub-agents.\n" +
|
|
255
|
+
'</identity>\n\n' +
|
|
256
|
+
'<directives>\n' +
|
|
257
|
+
'Synthesize these summaries into a natural, conversational response back to the user. ' +
|
|
258
|
+
'Address their original request directly (e.g., "I have completed your request to..."). ' +
|
|
259
|
+
'Provide ONE cohesive, unified overview of all changes made, using clear bullet points. ' +
|
|
260
|
+
'DO NOT list changes by task name or separate them by agent. ' +
|
|
261
|
+
'Be concise, helpful, and conclude by asking if they need any further adjustments.\n' +
|
|
262
|
+
'</directives>';
|
|
263
|
+
const synthesized = await compressTextUsingFlashLite(payloadWithContext, instruction);
|
|
247
264
|
finalSummary += synthesized + '\n\n';
|
|
248
265
|
}
|
|
249
266
|
catch (e) {
|
|
250
267
|
debugLog(`Synthesis failed, falling back to raw output: ${e}`);
|
|
251
268
|
finalSummary += rawSummaryData;
|
|
252
269
|
}
|
|
270
|
+
const currentUsage = peekTurnUsage();
|
|
271
|
+
const totalInputTokens = (currentUsage.promptTokens || 0) + (currentUsage.cachedTokens || 0);
|
|
253
272
|
p.log.info(`${pc.green('✓')} Sub-agent execution complete.\n` +
|
|
254
273
|
` Total tasks: ${graph.tasks.length} (${failedTasks} failed)\n` +
|
|
255
274
|
` Bus Activity: ${stats.activityCount} actions, ${stats.signalCount} signals\n` +
|
|
256
|
-
` Total Tokens: ${
|
|
275
|
+
` Total Tokens: ${currentUsage.totalTokenCount.toLocaleString()} ${pc.dim(`(Input: ${totalInputTokens.toLocaleString()}, Output: ${currentUsage.candidatesTokens.toLocaleString()})`)}`);
|
|
257
276
|
// Clear the bus persistence now that orchestration is done
|
|
258
277
|
await this.bus.cleanup();
|
|
259
278
|
this.locks.shutdown();
|
|
@@ -39,7 +39,7 @@ export declare class SubAgentRunner {
|
|
|
39
39
|
private inputTokens;
|
|
40
40
|
private outputTokens;
|
|
41
41
|
/** Max time without a tool call or response before the agent is considered stalled */
|
|
42
|
-
static readonly STALL_TIMEOUT_MS =
|
|
42
|
+
static readonly STALL_TIMEOUT_MS = 300000;
|
|
43
43
|
constructor(taskId: string, intent: string, workspaceRoot: string, bus: MessageBus, locks: FileLockRegistry, globalContext: string, onProgress?: ((msg: string) => void) | undefined);
|
|
44
44
|
/**
|
|
45
45
|
* Constructs the base system instruction for this specific agent.
|
|
@@ -27,7 +27,7 @@ export class SubAgentRunner {
|
|
|
27
27
|
inputTokens = 0;
|
|
28
28
|
outputTokens = 0;
|
|
29
29
|
/** Max time without a tool call or response before the agent is considered stalled */
|
|
30
|
-
static STALL_TIMEOUT_MS =
|
|
30
|
+
static STALL_TIMEOUT_MS = 300_000;
|
|
31
31
|
constructor(taskId, intent, workspaceRoot, bus, locks, globalContext, onProgress) {
|
|
32
32
|
this.taskId = taskId;
|
|
33
33
|
this.intent = intent;
|
|
@@ -38,8 +38,8 @@ export class SubAgentRunner {
|
|
|
38
38
|
this.onProgress = onProgress;
|
|
39
39
|
let model = getGlobalActiveModel();
|
|
40
40
|
if (model === GEMINI_MODELS.AUTO)
|
|
41
|
-
model = GEMINI_MODELS.
|
|
42
|
-
// Sub-agents default to flash-3.
|
|
41
|
+
model = GEMINI_MODELS.FLASH;
|
|
42
|
+
// Sub-agents default to flash-3.6 for better reasoning capabilities
|
|
43
43
|
this.chat = new ProxyChatSession(model, this.buildSystemInstruction(), [{ functionDeclarations: getScopedToolDeclarations() }], {
|
|
44
44
|
maxOutputTokens: MAX_OUTPUT_TOKENS,
|
|
45
45
|
temperature: 0.3, // Lower temperature for more focused execution
|
|
@@ -51,18 +51,24 @@ export class SubAgentRunner {
|
|
|
51
51
|
* Constructs the base system instruction for this specific agent.
|
|
52
52
|
*/
|
|
53
53
|
buildSystemInstruction() {
|
|
54
|
-
return (
|
|
54
|
+
return (`<identity>\n` +
|
|
55
|
+
`You are an autonomous Senior software developer sub-agent executing a specific portion of a larger task.\n` +
|
|
56
|
+
`</identity>\n\n` +
|
|
57
|
+
`<task_info>\n` +
|
|
55
58
|
`Your task ID is: ${this.taskId}\n` +
|
|
56
|
-
`Your objective: ${this.intent}\n
|
|
57
|
-
|
|
59
|
+
`Your objective: ${this.intent}\n` +
|
|
60
|
+
`</task_info>\n\n` +
|
|
61
|
+
`<reference_context>\n` +
|
|
62
|
+
`DO NOT IMPLEMENT THIS FULL REQUEST. THIS IS JUST FOR CONTEXT.\n\n` +
|
|
58
63
|
`${this.globalContext}\n` +
|
|
59
|
-
|
|
60
|
-
|
|
64
|
+
`</reference_context>\n\n` +
|
|
65
|
+
`<critical_guidelines>\n` +
|
|
61
66
|
`1. You are ONE worker in a team. You MUST ONLY focus on your specific objective: "${this.intent}".\n` +
|
|
62
67
|
`2. DO NOT attempt to fulfill the entire original user request in the reference context. Other agents are handling the other parts.\n` +
|
|
63
68
|
`3. You are part of a parallelized system. Use 'post_message' to coordinate if you discover breaking changes.\n` +
|
|
64
69
|
`4. When you have completed your objective, stop using tools and provide a final summary of your work.\n` +
|
|
65
|
-
`5. If you encounter an insurmountable error, provide a summary of what went wrong so the orchestrator can re-assign or fix it
|
|
70
|
+
`5. If you encounter an insurmountable error, provide a summary of what went wrong so the orchestrator can re-assign or fix it.\n` +
|
|
71
|
+
`</critical_guidelines>`);
|
|
66
72
|
}
|
|
67
73
|
/**
|
|
68
74
|
* Updates the heartbeat. Passed to `executeScopedTool` to ensure the agent
|
|
@@ -126,8 +132,10 @@ export class SubAgentRunner {
|
|
|
126
132
|
toolResponses.push({
|
|
127
133
|
functionResponse: {
|
|
128
134
|
name: call.name,
|
|
129
|
-
response: {
|
|
130
|
-
|
|
135
|
+
response: {
|
|
136
|
+
error: 'You have already made this exact tool call previously. Please review your context history or try a different action.',
|
|
137
|
+
},
|
|
138
|
+
},
|
|
131
139
|
});
|
|
132
140
|
continue;
|
|
133
141
|
}
|
|
@@ -151,7 +159,9 @@ export class SubAgentRunner {
|
|
|
151
159
|
output: responseData.output !== undefined ? responseData.output : responseData,
|
|
152
160
|
...(responseData.error ? { error: responseData.error } : {}),
|
|
153
161
|
...(responseData.inlineData ? { inlineData: responseData.inlineData } : {}),
|
|
154
|
-
...(responseData._orchestrationWarning
|
|
162
|
+
...(responseData._orchestrationWarning
|
|
163
|
+
? { _orchestrationWarning: responseData._orchestrationWarning }
|
|
164
|
+
: {}),
|
|
155
165
|
},
|
|
156
166
|
},
|
|
157
167
|
});
|
|
@@ -201,7 +211,7 @@ export class SubAgentRunner {
|
|
|
201
211
|
if (usage) {
|
|
202
212
|
const input = (usage.promptTokens || 0) + (usage.cachedTokens || 0);
|
|
203
213
|
const output = usage.candidatesTokens || 0;
|
|
204
|
-
const tokens = usage.totalTokenCount ||
|
|
214
|
+
const tokens = usage.totalTokenCount || input + output;
|
|
205
215
|
this.inputTokens += input;
|
|
206
216
|
this.outputTokens += output;
|
|
207
217
|
this.creditsUsed += tokens;
|
|
@@ -1,18 +1,4 @@
|
|
|
1
1
|
import type { Content, Tool, ToolConfig, FunctionCall } from '@google/generative-ai';
|
|
2
|
-
/**
|
|
3
|
-
* ============================================================================
|
|
4
|
-
* PROXY CLIENT SERVICE
|
|
5
|
-
* ============================================================================
|
|
6
|
-
* Facilitates stream-based communication with the secure, Firebase-authenticated
|
|
7
|
-
* serverless Gemini content generation proxy.
|
|
8
|
-
*
|
|
9
|
-
* Core Capabilities:
|
|
10
|
-
* - Server-Sent Events (SSE) parsing for thoughts, text, and function calls.
|
|
11
|
-
* - Secure Authentication handling (Firebase ID Tokens).
|
|
12
|
-
* - Real-time stream-callback piping for instant responses.
|
|
13
|
-
* - Accurate token usage, credit consumption, and grounding metadata parsing.
|
|
14
|
-
* ============================================================================
|
|
15
|
-
*/
|
|
16
2
|
/**
|
|
17
3
|
* Metadata containing real-time proxy token and credit usage diagnostics.
|
|
18
4
|
*/
|
|
@@ -28,6 +14,22 @@ export interface ProxyUsageMetadata {
|
|
|
28
14
|
/** The remaining balance left in the user's account. */
|
|
29
15
|
remainingBalance: number;
|
|
30
16
|
}
|
|
17
|
+
export declare function getAndResetTurnUsage(): {
|
|
18
|
+
promptTokens: number;
|
|
19
|
+
candidatesTokens: number;
|
|
20
|
+
cachedTokens: number;
|
|
21
|
+
totalTokenCount: number;
|
|
22
|
+
creditsUsed: number;
|
|
23
|
+
remainingBalance: number | undefined;
|
|
24
|
+
};
|
|
25
|
+
export declare function peekTurnUsage(): {
|
|
26
|
+
promptTokens: number;
|
|
27
|
+
candidatesTokens: number;
|
|
28
|
+
cachedTokens: number;
|
|
29
|
+
totalTokenCount: number;
|
|
30
|
+
creditsUsed: number;
|
|
31
|
+
remainingBalance: number | undefined;
|
|
32
|
+
};
|
|
31
33
|
/**
|
|
32
34
|
* Client service interacting directly with the serverless Gemini proxy endpoint.
|
|
33
35
|
* Ensures authorization via Firebase token passing and parses streamed content.
|