@google/gemini-cli-core 0.19.0-preview.0 → 0.20.0-nightly.20251127.5bed97064

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.
Files changed (91) hide show
  1. package/dist/google-gemini-cli-core-0.20.0-nightly.20251126.d2a6cff4d.tgz +0 -0
  2. package/dist/src/availability/modelAvailabilityService.d.ts +1 -1
  3. package/dist/src/availability/modelAvailabilityService.js +2 -2
  4. package/dist/src/availability/modelAvailabilityService.js.map +1 -1
  5. package/dist/src/availability/modelAvailabilityService.test.js +3 -3
  6. package/dist/src/availability/modelAvailabilityService.test.js.map +1 -1
  7. package/dist/src/availability/policyHelpers.d.ts +21 -0
  8. package/dist/src/availability/policyHelpers.js +41 -0
  9. package/dist/src/availability/policyHelpers.js.map +1 -0
  10. package/dist/src/availability/policyHelpers.test.d.ts +6 -0
  11. package/dist/src/availability/policyHelpers.test.js +51 -0
  12. package/dist/src/availability/policyHelpers.test.js.map +1 -0
  13. package/dist/src/config/config.d.ts +8 -1
  14. package/dist/src/config/config.js +17 -1
  15. package/dist/src/config/config.js.map +1 -1
  16. package/dist/src/config/config.test.js +14 -0
  17. package/dist/src/config/config.test.js.map +1 -1
  18. package/dist/src/core/client.js +4 -37
  19. package/dist/src/core/client.js.map +1 -1
  20. package/dist/src/core/client.test.js +45 -0
  21. package/dist/src/core/client.test.js.map +1 -1
  22. package/dist/src/core/coreToolHookTriggers.d.ts +55 -0
  23. package/dist/src/core/coreToolHookTriggers.js +244 -0
  24. package/dist/src/core/coreToolHookTriggers.js.map +1 -0
  25. package/dist/src/core/coreToolScheduler.js +11 -2
  26. package/dist/src/core/coreToolScheduler.js.map +1 -1
  27. package/dist/src/core/coreToolScheduler.test.js +66 -1
  28. package/dist/src/core/coreToolScheduler.test.js.map +1 -1
  29. package/dist/src/core/geminiChat.js +90 -18
  30. package/dist/src/core/geminiChat.js.map +1 -1
  31. package/dist/src/core/geminiChat.test.js +14 -3
  32. package/dist/src/core/geminiChat.test.js.map +1 -1
  33. package/dist/src/core/geminiChatHookTriggers.d.ts +64 -0
  34. package/dist/src/core/geminiChatHookTriggers.js +136 -0
  35. package/dist/src/core/geminiChatHookTriggers.js.map +1 -0
  36. package/dist/src/core/prompts.js +38 -19
  37. package/dist/src/core/prompts.js.map +1 -1
  38. package/dist/src/fallback/handler.js +105 -28
  39. package/dist/src/fallback/handler.js.map +1 -1
  40. package/dist/src/fallback/handler.test.js +145 -0
  41. package/dist/src/fallback/handler.test.js.map +1 -1
  42. package/dist/src/fallback/types.d.ts +8 -0
  43. package/dist/src/generated/git-commit.d.ts +2 -2
  44. package/dist/src/generated/git-commit.js +2 -2
  45. package/dist/src/generated/git-commit.js.map +1 -1
  46. package/dist/src/index.d.ts +1 -0
  47. package/dist/src/index.js +1 -0
  48. package/dist/src/index.js.map +1 -1
  49. package/dist/src/mcp/auth-provider.d.ts +16 -0
  50. package/dist/src/mcp/auth-provider.js +7 -0
  51. package/dist/src/mcp/auth-provider.js.map +1 -0
  52. package/dist/src/mcp/google-auth-provider.d.ts +10 -2
  53. package/dist/src/mcp/google-auth-provider.js +28 -0
  54. package/dist/src/mcp/google-auth-provider.js.map +1 -1
  55. package/dist/src/mcp/google-auth-provider.test.js +45 -0
  56. package/dist/src/mcp/google-auth-provider.test.js.map +1 -1
  57. package/dist/src/mcp/sa-impersonation-provider.d.ts +2 -2
  58. package/dist/src/mcp/sa-impersonation-provider.js.map +1 -1
  59. package/dist/src/services/chatCompressionService.js +2 -2
  60. package/dist/src/services/chatCompressionService.js.map +1 -1
  61. package/dist/src/services/chatCompressionService.test.js +7 -0
  62. package/dist/src/services/chatCompressionService.test.js.map +1 -1
  63. package/dist/src/tools/mcp-client-manager.d.ts +1 -0
  64. package/dist/src/tools/mcp-client-manager.js +13 -0
  65. package/dist/src/tools/mcp-client-manager.js.map +1 -1
  66. package/dist/src/tools/mcp-client-manager.test.js +35 -0
  67. package/dist/src/tools/mcp-client-manager.test.js.map +1 -1
  68. package/dist/src/tools/mcp-client.d.ts +1 -0
  69. package/dist/src/tools/mcp-client.js +4 -1
  70. package/dist/src/tools/mcp-client.js.map +1 -1
  71. package/dist/src/tools/mcp-client.test.js +48 -0
  72. package/dist/src/tools/mcp-client.test.js.map +1 -1
  73. package/dist/src/tools/shell.js +43 -3
  74. package/dist/src/tools/shell.js.map +1 -1
  75. package/dist/src/tools/shell.test.js +23 -4
  76. package/dist/src/tools/shell.test.js.map +1 -1
  77. package/dist/src/utils/exitCodes.d.ts +12 -0
  78. package/dist/src/utils/exitCodes.js +13 -0
  79. package/dist/src/utils/exitCodes.js.map +1 -0
  80. package/dist/src/utils/memoryDiscovery.js +5 -1
  81. package/dist/src/utils/memoryDiscovery.js.map +1 -1
  82. package/dist/src/utils/memoryDiscovery.test.js +28 -0
  83. package/dist/src/utils/memoryDiscovery.test.js.map +1 -1
  84. package/dist/src/utils/tokenCalculation.d.ts +19 -0
  85. package/dist/src/utils/tokenCalculation.js +70 -0
  86. package/dist/src/utils/tokenCalculation.js.map +1 -0
  87. package/dist/src/utils/tokenCalculation.test.d.ts +6 -0
  88. package/dist/src/utils/tokenCalculation.test.js +78 -0
  89. package/dist/src/utils/tokenCalculation.test.js.map +1 -0
  90. package/dist/tsconfig.tsbuildinfo +1 -1
  91. package/package.json +1 -1
@@ -0,0 +1,70 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2025 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ // Token estimation constants
7
+ // ASCII characters (0-127) are roughly 4 chars per token
8
+ const ASCII_TOKENS_PER_CHAR = 0.25;
9
+ // Non-ASCII characters (including CJK) are often 1-2 tokens per char.
10
+ // We use 1.3 as a conservative estimate to avoid underestimation.
11
+ const NON_ASCII_TOKENS_PER_CHAR = 1.3;
12
+ /**
13
+ * Estimates token count for parts synchronously using a heuristic.
14
+ * - Text: character-based heuristic (ASCII vs CJK).
15
+ * - Non-text (Tools, etc): JSON string length / 4.
16
+ */
17
+ export function estimateTokenCountSync(parts) {
18
+ let totalTokens = 0;
19
+ for (const part of parts) {
20
+ if (typeof part.text === 'string') {
21
+ for (const char of part.text) {
22
+ if (char.codePointAt(0) <= 127) {
23
+ totalTokens += ASCII_TOKENS_PER_CHAR;
24
+ }
25
+ else {
26
+ totalTokens += NON_ASCII_TOKENS_PER_CHAR;
27
+ }
28
+ }
29
+ }
30
+ else {
31
+ // For non-text parts (functionCall, functionResponse, executableCode, etc.),
32
+ // we fallback to the JSON string length heuristic.
33
+ // Note: This is an approximation.
34
+ totalTokens += JSON.stringify(part).length / 4;
35
+ }
36
+ }
37
+ return Math.floor(totalTokens);
38
+ }
39
+ /**
40
+ * Calculates the token count of the request.
41
+ * If the request contains only text or tools, it estimates the token count locally.
42
+ * If the request contains media (images, files), it uses the countTokens API.
43
+ */
44
+ export async function calculateRequestTokenCount(request, contentGenerator, model) {
45
+ const parts = Array.isArray(request)
46
+ ? request.map((p) => (typeof p === 'string' ? { text: p } : p))
47
+ : typeof request === 'string'
48
+ ? [{ text: request }]
49
+ : [request];
50
+ // Use countTokens API only for heavy media parts that are hard to estimate.
51
+ const hasMedia = parts.some((p) => {
52
+ const isMedia = 'inlineData' in p || 'fileData' in p;
53
+ return isMedia;
54
+ });
55
+ if (hasMedia) {
56
+ try {
57
+ const response = await contentGenerator.countTokens({
58
+ model,
59
+ contents: [{ role: 'user', parts }],
60
+ });
61
+ return response.totalTokens ?? 0;
62
+ }
63
+ catch {
64
+ // Fallback to local estimation if the API call fails
65
+ return estimateTokenCountSync(parts);
66
+ }
67
+ }
68
+ return estimateTokenCountSync(parts);
69
+ }
70
+ //# sourceMappingURL=tokenCalculation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tokenCalculation.js","sourceRoot":"","sources":["../../../src/utils/tokenCalculation.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,6BAA6B;AAC7B,yDAAyD;AACzD,MAAM,qBAAqB,GAAG,IAAI,CAAC;AACnC,sEAAsE;AACtE,kEAAkE;AAClE,MAAM,yBAAyB,GAAG,GAAG,CAAC;AAEtC;;;;GAIG;AACH,MAAM,UAAU,sBAAsB,CAAC,KAAa;IAClD,IAAI,WAAW,GAAG,CAAC,CAAC;IACpB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,OAAO,IAAI,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YAClC,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;gBAC7B,IAAI,IAAI,CAAC,WAAW,CAAC,CAAC,CAAE,IAAI,GAAG,EAAE,CAAC;oBAChC,WAAW,IAAI,qBAAqB,CAAC;gBACvC,CAAC;qBAAM,CAAC;oBACN,WAAW,IAAI,yBAAyB,CAAC;gBAC3C,CAAC;YACH,CAAC;QACH,CAAC;aAAM,CAAC;YACN,6EAA6E;YAC7E,mDAAmD;YACnD,kCAAkC;YAClC,WAAW,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;QACjD,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;AACjC,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,0BAA0B,CAC9C,OAAsB,EACtB,gBAAkC,EAClC,KAAa;IAEb,MAAM,KAAK,GAAW,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC;QAC1C,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC/D,CAAC,CAAC,OAAO,OAAO,KAAK,QAAQ;YAC3B,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;YACrB,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;IAEhB,4EAA4E;IAC5E,MAAM,QAAQ,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE;QAChC,MAAM,OAAO,GAAG,YAAY,IAAI,CAAC,IAAI,UAAU,IAAI,CAAC,CAAC;QACrD,OAAO,OAAO,CAAC;IACjB,CAAC,CAAC,CAAC;IAEH,IAAI,QAAQ,EAAE,CAAC;QACb,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,gBAAgB,CAAC,WAAW,CAAC;gBAClD,KAAK;gBACL,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;aACpC,CAAC,CAAC;YACH,OAAO,QAAQ,CAAC,WAAW,IAAI,CAAC,CAAC;QACnC,CAAC;QAAC,MAAM,CAAC;YACP,qDAAqD;YACrD,OAAO,sBAAsB,CAAC,KAAK,CAAC,CAAC;QACvC,CAAC;IACH,CAAC;IAED,OAAO,sBAAsB,CAAC,KAAK,CAAC,CAAC;AACvC,CAAC"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2025 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ export {};
@@ -0,0 +1,78 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2025 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import { describe, it, expect, vi } from 'vitest';
7
+ import { calculateRequestTokenCount } from './tokenCalculation.js';
8
+ describe('calculateRequestTokenCount', () => {
9
+ const mockContentGenerator = {
10
+ countTokens: vi.fn(),
11
+ };
12
+ const model = 'gemini-pro';
13
+ it('should use countTokens API for media requests (images/files)', async () => {
14
+ vi.mocked(mockContentGenerator.countTokens).mockResolvedValue({
15
+ totalTokens: 100,
16
+ });
17
+ const request = [{ inlineData: { mimeType: 'image/png', data: 'data' } }];
18
+ const count = await calculateRequestTokenCount(request, mockContentGenerator, model);
19
+ expect(count).toBe(100);
20
+ expect(mockContentGenerator.countTokens).toHaveBeenCalled();
21
+ });
22
+ it('should estimate tokens locally for tool calls', async () => {
23
+ vi.mocked(mockContentGenerator.countTokens).mockClear();
24
+ const request = [{ functionCall: { name: 'foo', args: { bar: 'baz' } } }];
25
+ const count = await calculateRequestTokenCount(request, mockContentGenerator, model);
26
+ // Estimation logic: JSON.stringify(part).length / 4
27
+ // JSON: {"functionCall":{"name":"foo","args":{"bar":"baz"}}}
28
+ // Length: ~53 chars. 53 / 4 = 13.25 -> 13.
29
+ expect(count).toBeGreaterThan(0);
30
+ expect(mockContentGenerator.countTokens).not.toHaveBeenCalled();
31
+ });
32
+ it('should estimate tokens locally for simple ASCII text', async () => {
33
+ vi.mocked(mockContentGenerator.countTokens).mockClear();
34
+ // 12 chars. 12 * 0.25 = 3 tokens.
35
+ const request = 'Hello world!';
36
+ const count = await calculateRequestTokenCount(request, mockContentGenerator, model);
37
+ expect(count).toBe(3);
38
+ expect(mockContentGenerator.countTokens).not.toHaveBeenCalled();
39
+ });
40
+ it('should estimate tokens locally for CJK text with higher weight', async () => {
41
+ vi.mocked(mockContentGenerator.countTokens).mockClear();
42
+ // 2 chars. 2 * 1.3 = 2.6 -> floor(2.6) = 2.
43
+ // Old logic would be 2/4 = 0.5 -> 0.
44
+ const request = '你好';
45
+ const count = await calculateRequestTokenCount(request, mockContentGenerator, model);
46
+ expect(count).toBeGreaterThanOrEqual(2);
47
+ expect(mockContentGenerator.countTokens).not.toHaveBeenCalled();
48
+ });
49
+ it('should handle mixed content', async () => {
50
+ vi.mocked(mockContentGenerator.countTokens).mockClear();
51
+ // 'Hi': 2 * 0.25 = 0.5
52
+ // '你好': 2 * 1.3 = 2.6
53
+ // Total: 3.1 -> 3
54
+ const request = 'Hi你好';
55
+ const count = await calculateRequestTokenCount(request, mockContentGenerator, model);
56
+ expect(count).toBe(3);
57
+ expect(mockContentGenerator.countTokens).not.toHaveBeenCalled();
58
+ });
59
+ it('should handle empty text', async () => {
60
+ const request = '';
61
+ const count = await calculateRequestTokenCount(request, mockContentGenerator, model);
62
+ expect(count).toBe(0);
63
+ });
64
+ it('should fallback to local estimation when countTokens API fails', async () => {
65
+ vi.mocked(mockContentGenerator.countTokens).mockRejectedValue(new Error('API error'));
66
+ const request = [
67
+ { text: 'Hello' },
68
+ { inlineData: { mimeType: 'image/png', data: 'data' } },
69
+ ];
70
+ const count = await calculateRequestTokenCount(request, mockContentGenerator, model);
71
+ // Should fallback to estimation:
72
+ // 'Hello': 5 chars * 0.25 = 1.25
73
+ // inlineData: JSON.stringify length / 4
74
+ expect(count).toBeGreaterThan(0);
75
+ expect(mockContentGenerator.countTokens).toHaveBeenCalled();
76
+ });
77
+ });
78
+ //# sourceMappingURL=tokenCalculation.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tokenCalculation.test.js","sourceRoot":"","sources":["../../../src/utils/tokenCalculation.test.ts"],"names":[],"mappings":"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"}