@kaitranntt/ccs 4.4.0 → 5.0.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/README.md +98 -7
- package/VERSION +1 -1
- package/config/base-agy.settings.json +10 -0
- package/config/base-codex.settings.json +10 -0
- package/config/base-gemini.settings.json +10 -0
- package/dist/auth/auth-commands.d.ts +52 -0
- package/dist/auth/auth-commands.d.ts.map +1 -0
- package/dist/auth/auth-commands.js +479 -0
- package/dist/auth/auth-commands.js.map +1 -0
- package/dist/auth/profile-detector.d.ts +68 -0
- package/dist/auth/profile-detector.d.ts.map +1 -0
- package/dist/auth/profile-detector.js +209 -0
- package/dist/auth/profile-detector.js.map +1 -0
- package/dist/auth/profile-registry.d.ts +60 -0
- package/dist/auth/profile-registry.d.ts.map +1 -0
- package/dist/auth/profile-registry.js +188 -0
- package/dist/auth/profile-registry.js.map +1 -0
- package/dist/ccs.d.ts +10 -0
- package/dist/ccs.d.ts.map +1 -0
- package/dist/ccs.js +320 -0
- package/dist/ccs.js.map +1 -0
- package/dist/cliproxy/auth-handler.d.ts +95 -0
- package/dist/cliproxy/auth-handler.d.ts.map +1 -0
- package/dist/cliproxy/auth-handler.js +443 -0
- package/dist/cliproxy/auth-handler.js.map +1 -0
- package/dist/cliproxy/base-config-loader.d.ts +42 -0
- package/dist/cliproxy/base-config-loader.d.ts.map +1 -0
- package/dist/cliproxy/base-config-loader.js +123 -0
- package/dist/cliproxy/base-config-loader.js.map +1 -0
- package/dist/cliproxy/binary-manager.d.ts +104 -0
- package/dist/cliproxy/binary-manager.d.ts.map +1 -0
- package/dist/cliproxy/binary-manager.js +567 -0
- package/dist/cliproxy/binary-manager.js.map +1 -0
- package/dist/cliproxy/cliproxy-executor.d.ts +33 -0
- package/dist/cliproxy/cliproxy-executor.d.ts.map +1 -0
- package/dist/cliproxy/cliproxy-executor.js +297 -0
- package/dist/cliproxy/cliproxy-executor.js.map +1 -0
- package/dist/cliproxy/config-generator.d.ts +89 -0
- package/dist/cliproxy/config-generator.d.ts.map +1 -0
- package/dist/cliproxy/config-generator.js +263 -0
- package/dist/cliproxy/config-generator.js.map +1 -0
- package/dist/cliproxy/index.d.ts +13 -0
- package/dist/cliproxy/index.d.ts.map +1 -0
- package/dist/cliproxy/index.js +62 -0
- package/dist/cliproxy/index.js.map +1 -0
- package/dist/cliproxy/platform-detector.d.ts +48 -0
- package/dist/cliproxy/platform-detector.d.ts.map +1 -0
- package/dist/cliproxy/platform-detector.js +118 -0
- package/dist/cliproxy/platform-detector.js.map +1 -0
- package/dist/cliproxy/types.d.ts +169 -0
- package/dist/cliproxy/types.d.ts.map +1 -0
- package/dist/cliproxy/types.js +7 -0
- package/dist/cliproxy/types.js.map +1 -0
- package/dist/commands/doctor-command.d.ts +10 -0
- package/dist/commands/doctor-command.d.ts.map +1 -0
- package/dist/commands/doctor-command.js +44 -0
- package/dist/commands/doctor-command.js.map +1 -0
- package/dist/commands/help-command.d.ts +5 -0
- package/dist/commands/help-command.d.ts.map +1 -0
- package/dist/commands/help-command.js +104 -0
- package/dist/commands/help-command.js.map +1 -0
- package/dist/commands/install-command.d.ts +14 -0
- package/dist/commands/install-command.d.ts.map +1 -0
- package/dist/commands/install-command.js +39 -0
- package/dist/commands/install-command.js.map +1 -0
- package/dist/commands/shell-completion-command.d.ts +10 -0
- package/dist/commands/shell-completion-command.d.ts.map +1 -0
- package/dist/commands/shell-completion-command.js +85 -0
- package/dist/commands/shell-completion-command.js.map +1 -0
- package/dist/commands/sync-command.d.ts +10 -0
- package/dist/commands/sync-command.d.ts.map +1 -0
- package/dist/commands/sync-command.js +59 -0
- package/dist/commands/sync-command.js.map +1 -0
- package/dist/commands/update-command.d.ts +12 -0
- package/dist/commands/update-command.d.ts.map +1 -0
- package/dist/commands/update-command.js +295 -0
- package/dist/commands/update-command.js.map +1 -0
- package/dist/commands/version-command.d.ts +10 -0
- package/dist/commands/version-command.d.ts.map +1 -0
- package/dist/commands/version-command.js +100 -0
- package/dist/commands/version-command.js.map +1 -0
- package/dist/delegation/delegation-handler.d.ts +60 -0
- package/dist/delegation/delegation-handler.d.ts.map +1 -0
- package/dist/delegation/delegation-handler.js +174 -0
- package/dist/delegation/delegation-handler.js.map +1 -0
- package/dist/delegation/headless-executor.d.ts +114 -0
- package/dist/delegation/headless-executor.d.ts.map +1 -0
- package/dist/delegation/headless-executor.js +562 -0
- package/dist/delegation/headless-executor.js.map +1 -0
- package/dist/delegation/result-formatter.d.ts +108 -0
- package/dist/delegation/result-formatter.d.ts.map +1 -0
- package/dist/delegation/result-formatter.js +391 -0
- package/dist/delegation/result-formatter.js.map +1 -0
- package/dist/delegation/session-manager.d.ts +58 -0
- package/dist/delegation/session-manager.d.ts.map +1 -0
- package/dist/delegation/session-manager.js +153 -0
- package/dist/delegation/session-manager.js.map +1 -0
- package/dist/delegation/settings-parser.d.ts +31 -0
- package/dist/delegation/settings-parser.d.ts.map +1 -0
- package/dist/delegation/settings-parser.js +107 -0
- package/dist/delegation/settings-parser.js.map +1 -0
- package/dist/glmt/delta-accumulator.d.ts +210 -0
- package/dist/glmt/delta-accumulator.d.ts.map +1 -0
- package/dist/glmt/delta-accumulator.js +351 -0
- package/dist/glmt/delta-accumulator.js.map +1 -0
- package/dist/glmt/glmt-proxy.d.ts +72 -0
- package/dist/glmt/glmt-proxy.d.ts.map +1 -0
- package/dist/glmt/glmt-proxy.js +427 -0
- package/dist/glmt/glmt-proxy.js.map +1 -0
- package/dist/glmt/glmt-transformer.d.ts +265 -0
- package/dist/glmt/glmt-transformer.d.ts.map +1 -0
- package/dist/glmt/glmt-transformer.js +832 -0
- package/dist/glmt/glmt-transformer.js.map +1 -0
- package/dist/glmt/locale-enforcer.d.ts +38 -0
- package/dist/glmt/locale-enforcer.d.ts.map +1 -0
- package/dist/glmt/locale-enforcer.js +69 -0
- package/dist/glmt/locale-enforcer.js.map +1 -0
- package/dist/glmt/reasoning-enforcer.d.ts +52 -0
- package/dist/glmt/reasoning-enforcer.d.ts.map +1 -0
- package/dist/glmt/reasoning-enforcer.js +151 -0
- package/dist/glmt/reasoning-enforcer.js.map +1 -0
- package/dist/glmt/sse-parser.d.ts +47 -0
- package/dist/glmt/sse-parser.d.ts.map +1 -0
- package/dist/glmt/sse-parser.js +93 -0
- package/dist/glmt/sse-parser.js.map +1 -0
- package/dist/management/doctor.d.ts +104 -0
- package/dist/management/doctor.d.ts.map +1 -0
- package/dist/management/doctor.js +673 -0
- package/dist/management/doctor.js.map +1 -0
- package/dist/management/instance-manager.d.ts +57 -0
- package/dist/management/instance-manager.d.ts.map +1 -0
- package/dist/management/instance-manager.js +195 -0
- package/dist/management/instance-manager.js.map +1 -0
- package/dist/management/recovery-manager.d.ts +39 -0
- package/dist/management/recovery-manager.d.ts.map +1 -0
- package/dist/management/recovery-manager.js +141 -0
- package/dist/management/recovery-manager.js.map +1 -0
- package/dist/management/shared-manager.d.ts +47 -0
- package/dist/management/shared-manager.d.ts.map +1 -0
- package/dist/management/shared-manager.js +388 -0
- package/dist/management/shared-manager.js.map +1 -0
- package/dist/types/cli.d.ts +50 -0
- package/dist/types/cli.d.ts.map +1 -0
- package/dist/types/cli.js +16 -0
- package/dist/types/cli.js.map +1 -0
- package/dist/types/config.d.ts +51 -0
- package/dist/types/config.d.ts.map +1 -0
- package/dist/types/config.js +26 -0
- package/dist/types/config.js.map +1 -0
- package/dist/types/delegation.d.ts +61 -0
- package/dist/types/delegation.d.ts.map +1 -0
- package/dist/types/delegation.js +6 -0
- package/dist/types/delegation.js.map +1 -0
- package/dist/types/glmt.d.ts +95 -0
- package/dist/types/glmt.d.ts.map +1 -0
- package/dist/types/glmt.js +7 -0
- package/dist/types/glmt.js.map +1 -0
- package/dist/types/index.d.ts +13 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +16 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/utils.d.ts +36 -0
- package/dist/types/utils.d.ts.map +1 -0
- package/dist/types/utils.js +22 -0
- package/dist/types/utils.js.map +1 -0
- package/dist/utils/claude-detector.d.ts +14 -0
- package/dist/utils/claude-detector.d.ts.map +1 -0
- package/dist/utils/claude-detector.js +112 -0
- package/dist/utils/claude-detector.js.map +1 -0
- package/dist/utils/claude-dir-installer.d.ts +46 -0
- package/dist/utils/claude-dir-installer.d.ts.map +1 -0
- package/dist/utils/claude-dir-installer.js +289 -0
- package/dist/utils/claude-dir-installer.js.map +1 -0
- package/dist/utils/claude-symlink-manager.d.ts +61 -0
- package/dist/utils/claude-symlink-manager.d.ts.map +1 -0
- package/dist/utils/claude-symlink-manager.js +291 -0
- package/dist/utils/claude-symlink-manager.js.map +1 -0
- package/dist/utils/config-manager.d.ts +32 -0
- package/dist/utils/config-manager.d.ts.map +1 -0
- package/dist/utils/config-manager.js +143 -0
- package/dist/utils/config-manager.js.map +1 -0
- package/dist/utils/delegation-validator.d.ts +39 -0
- package/dist/utils/delegation-validator.d.ts.map +1 -0
- package/dist/utils/delegation-validator.js +161 -0
- package/dist/utils/delegation-validator.js.map +1 -0
- package/dist/utils/error-codes.d.ts +36 -0
- package/dist/utils/error-codes.d.ts.map +1 -0
- package/dist/utils/error-codes.js +63 -0
- package/dist/utils/error-codes.js.map +1 -0
- package/dist/utils/error-manager.d.ts +59 -0
- package/dist/utils/error-manager.d.ts.map +1 -0
- package/dist/utils/error-manager.js +228 -0
- package/dist/utils/error-manager.js.map +1 -0
- package/dist/utils/helpers.d.ts +27 -0
- package/dist/utils/helpers.d.ts.map +1 -0
- package/dist/utils/helpers.js +150 -0
- package/dist/utils/helpers.js.map +1 -0
- package/dist/utils/package-manager-detector.d.ts +14 -0
- package/dist/utils/package-manager-detector.d.ts.map +1 -0
- package/dist/utils/package-manager-detector.js +162 -0
- package/dist/utils/package-manager-detector.js.map +1 -0
- package/dist/utils/progress-indicator.d.ts +52 -0
- package/dist/utils/progress-indicator.d.ts.map +1 -0
- package/dist/utils/progress-indicator.js +102 -0
- package/dist/utils/progress-indicator.js.map +1 -0
- package/dist/utils/prompt.d.ts +29 -0
- package/dist/utils/prompt.d.ts.map +1 -0
- package/dist/utils/prompt.js +116 -0
- package/dist/utils/prompt.js.map +1 -0
- package/dist/utils/shell-completion.d.ts +52 -0
- package/dist/utils/shell-completion.d.ts.map +1 -0
- package/dist/utils/shell-completion.js +231 -0
- package/dist/utils/shell-completion.js.map +1 -0
- package/dist/utils/shell-executor.d.ts +15 -0
- package/dist/utils/shell-executor.d.ts.map +1 -0
- package/dist/utils/shell-executor.js +57 -0
- package/dist/utils/shell-executor.js.map +1 -0
- package/dist/utils/update-checker.d.ts +48 -0
- package/dist/utils/update-checker.d.ts.map +1 -0
- package/dist/utils/update-checker.js +241 -0
- package/dist/utils/update-checker.js.map +1 -0
- package/lib/ccs +21 -1907
- package/lib/ccs.ps1 +26 -1800
- package/lib/error-codes.ps1 +2 -1
- package/lib/prompt.ps1 +2 -2
- package/package.json +31 -11
- package/scripts/add-shebang.js +39 -0
- package/scripts/bump-version.sh +25 -37
- package/scripts/dev-install.sh +32 -11
- package/scripts/postinstall.js +29 -29
- package/bin/auth/auth-commands.js +0 -499
- package/bin/auth/profile-detector.js +0 -204
- package/bin/auth/profile-registry.js +0 -225
- package/bin/ccs.js +0 -1034
- package/bin/delegation/README.md +0 -191
- package/bin/delegation/delegation-handler.js +0 -212
- package/bin/delegation/headless-executor.js +0 -618
- package/bin/delegation/result-formatter.js +0 -485
- package/bin/delegation/session-manager.js +0 -157
- package/bin/delegation/settings-parser.js +0 -109
- package/bin/glmt/delta-accumulator.js +0 -276
- package/bin/glmt/glmt-proxy.js +0 -495
- package/bin/glmt/glmt-transformer.js +0 -999
- package/bin/glmt/locale-enforcer.js +0 -72
- package/bin/glmt/reasoning-enforcer.js +0 -173
- package/bin/glmt/sse-parser.js +0 -96
- package/bin/management/doctor.js +0 -721
- package/bin/management/instance-manager.js +0 -202
- package/bin/management/recovery-manager.js +0 -135
- package/bin/management/shared-manager.js +0 -402
- package/bin/utils/claude-detector.js +0 -73
- package/bin/utils/claude-dir-installer.js +0 -283
- package/bin/utils/claude-symlink-manager.js +0 -289
- package/bin/utils/config-manager.js +0 -103
- package/bin/utils/delegation-validator.js +0 -154
- package/bin/utils/error-codes.js +0 -59
- package/bin/utils/error-manager.js +0 -165
- package/bin/utils/helpers.js +0 -136
- package/bin/utils/progress-indicator.js +0 -111
- package/bin/utils/prompt.js +0 -134
- package/bin/utils/shell-completion.js +0 -256
- package/bin/utils/update-checker.js +0 -243
|
@@ -1,109 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
'use strict';
|
|
3
|
-
|
|
4
|
-
const fs = require('fs');
|
|
5
|
-
const path = require('path');
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Parses Claude Code settings for tool restrictions
|
|
9
|
-
*/
|
|
10
|
-
class SettingsParser {
|
|
11
|
-
/**
|
|
12
|
-
* Parse default permission mode from project settings
|
|
13
|
-
* @param {string} projectDir - Project directory (usually cwd)
|
|
14
|
-
* @returns {string} Default permission mode (e.g., 'acceptEdits', 'bypassPermissions', 'plan', 'default')
|
|
15
|
-
*/
|
|
16
|
-
static parseDefaultPermissionMode(projectDir) {
|
|
17
|
-
const settings = this._loadSettings(projectDir);
|
|
18
|
-
const permissions = settings.permissions || {};
|
|
19
|
-
|
|
20
|
-
// Priority: local > shared > fallback to 'acceptEdits'
|
|
21
|
-
const defaultMode = permissions.defaultMode || 'acceptEdits';
|
|
22
|
-
|
|
23
|
-
if (process.env.CCS_DEBUG) {
|
|
24
|
-
console.error(`[i] Permission mode from settings: ${defaultMode}`);
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
return defaultMode;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* Parse project settings for tool restrictions
|
|
32
|
-
* @param {string} projectDir - Project directory (usually cwd)
|
|
33
|
-
* @returns {Object} { allowedTools: string[], disallowedTools: string[] }
|
|
34
|
-
*/
|
|
35
|
-
static parseToolRestrictions(projectDir) {
|
|
36
|
-
const settings = this._loadSettings(projectDir);
|
|
37
|
-
const permissions = settings.permissions || {};
|
|
38
|
-
|
|
39
|
-
const allowed = permissions.allow || [];
|
|
40
|
-
const denied = permissions.deny || [];
|
|
41
|
-
|
|
42
|
-
if (process.env.CCS_DEBUG) {
|
|
43
|
-
console.error(`[i] Tool restrictions: ${allowed.length} allowed, ${denied.length} denied`);
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
return {
|
|
47
|
-
allowedTools: allowed,
|
|
48
|
-
disallowedTools: denied
|
|
49
|
-
};
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
/**
|
|
53
|
-
* Load and merge settings files (local overrides shared)
|
|
54
|
-
* @param {string} projectDir - Project directory
|
|
55
|
-
* @returns {Object} Merged settings
|
|
56
|
-
* @private
|
|
57
|
-
*/
|
|
58
|
-
static _loadSettings(projectDir) {
|
|
59
|
-
const claudeDir = path.join(projectDir, '.claude');
|
|
60
|
-
const sharedPath = path.join(claudeDir, 'settings.json');
|
|
61
|
-
const localPath = path.join(claudeDir, 'settings.local.json');
|
|
62
|
-
|
|
63
|
-
// Load shared settings
|
|
64
|
-
const shared = this._readJsonSafe(sharedPath) || {};
|
|
65
|
-
|
|
66
|
-
// Load local settings (overrides shared)
|
|
67
|
-
const local = this._readJsonSafe(localPath) || {};
|
|
68
|
-
|
|
69
|
-
// Merge permissions (local overrides shared)
|
|
70
|
-
return {
|
|
71
|
-
permissions: {
|
|
72
|
-
allow: [
|
|
73
|
-
...(shared.permissions?.allow || []),
|
|
74
|
-
...(local.permissions?.allow || [])
|
|
75
|
-
],
|
|
76
|
-
deny: [
|
|
77
|
-
...(shared.permissions?.deny || []),
|
|
78
|
-
...(local.permissions?.deny || [])
|
|
79
|
-
],
|
|
80
|
-
// Local defaultMode takes priority over shared
|
|
81
|
-
defaultMode: local.permissions?.defaultMode || shared.permissions?.defaultMode || null
|
|
82
|
-
}
|
|
83
|
-
};
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
/**
|
|
87
|
-
* Read JSON file safely (no throw)
|
|
88
|
-
* @param {string} filePath - Path to JSON file
|
|
89
|
-
* @returns {Object|null} Parsed JSON or null
|
|
90
|
-
* @private
|
|
91
|
-
*/
|
|
92
|
-
static _readJsonSafe(filePath) {
|
|
93
|
-
try {
|
|
94
|
-
if (!fs.existsSync(filePath)) {
|
|
95
|
-
return null;
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
const content = fs.readFileSync(filePath, 'utf8');
|
|
99
|
-
return JSON.parse(content);
|
|
100
|
-
} catch (error) {
|
|
101
|
-
if (process.env.CCS_DEBUG) {
|
|
102
|
-
console.warn(`[!] Failed to read settings: ${filePath}: ${error.message}`);
|
|
103
|
-
}
|
|
104
|
-
return null;
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
module.exports = { SettingsParser };
|
|
@@ -1,276 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
'use strict';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* DeltaAccumulator - Maintain state across streaming deltas
|
|
6
|
-
*
|
|
7
|
-
* Tracks:
|
|
8
|
-
* - Message metadata (id, model, role)
|
|
9
|
-
* - Content blocks (thinking, text)
|
|
10
|
-
* - Current block index
|
|
11
|
-
* - Accumulated content
|
|
12
|
-
*
|
|
13
|
-
* Usage:
|
|
14
|
-
* const acc = new DeltaAccumulator(thinkingConfig);
|
|
15
|
-
* const events = transformer.transformDelta(openaiEvent, acc);
|
|
16
|
-
*/
|
|
17
|
-
class DeltaAccumulator {
|
|
18
|
-
constructor(thinkingConfig = {}, options = {}) {
|
|
19
|
-
this.thinkingConfig = thinkingConfig;
|
|
20
|
-
this.messageId = 'msg_' + Date.now() + '_' + Math.random().toString(36).substring(7);
|
|
21
|
-
this.model = null;
|
|
22
|
-
this.role = 'assistant';
|
|
23
|
-
|
|
24
|
-
// Content blocks
|
|
25
|
-
this.contentBlocks = [];
|
|
26
|
-
this.currentBlockIndex = -1;
|
|
27
|
-
|
|
28
|
-
// Tool calls tracking
|
|
29
|
-
this.toolCalls = [];
|
|
30
|
-
this.toolCallsIndex = {};
|
|
31
|
-
|
|
32
|
-
// Buffers
|
|
33
|
-
this.thinkingBuffer = '';
|
|
34
|
-
this.textBuffer = '';
|
|
35
|
-
|
|
36
|
-
// C-02 Fix: Limits to prevent unbounded accumulation
|
|
37
|
-
this.maxBlocks = options.maxBlocks || 100;
|
|
38
|
-
this.maxBufferSize = options.maxBufferSize || 10 * 1024 * 1024; // 10MB
|
|
39
|
-
|
|
40
|
-
// Loop detection configuration
|
|
41
|
-
this.loopDetectionThreshold = options.loopDetectionThreshold || 3;
|
|
42
|
-
this.loopDetected = false;
|
|
43
|
-
|
|
44
|
-
// State flags
|
|
45
|
-
this.messageStarted = false;
|
|
46
|
-
this.finalized = false;
|
|
47
|
-
this.usageReceived = false; // Track if usage data has arrived
|
|
48
|
-
|
|
49
|
-
// Statistics
|
|
50
|
-
this.inputTokens = 0;
|
|
51
|
-
this.outputTokens = 0;
|
|
52
|
-
this.finishReason = null;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
/**
|
|
56
|
-
* Get current content block
|
|
57
|
-
* @returns {Object|null} Current block or null
|
|
58
|
-
*/
|
|
59
|
-
getCurrentBlock() {
|
|
60
|
-
if (this.currentBlockIndex >= 0 && this.currentBlockIndex < this.contentBlocks.length) {
|
|
61
|
-
return this.contentBlocks[this.currentBlockIndex];
|
|
62
|
-
}
|
|
63
|
-
return null;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
/**
|
|
67
|
-
* Start new content block
|
|
68
|
-
* @param {string} type - Block type ('thinking', 'text', or 'tool_use')
|
|
69
|
-
* @returns {Object} New block
|
|
70
|
-
*/
|
|
71
|
-
startBlock(type) {
|
|
72
|
-
// C-02 Fix: Enforce max blocks limit
|
|
73
|
-
if (this.contentBlocks.length >= this.maxBlocks) {
|
|
74
|
-
throw new Error(`Maximum ${this.maxBlocks} content blocks exceeded (DoS protection)`);
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
this.currentBlockIndex++;
|
|
78
|
-
const block = {
|
|
79
|
-
index: this.currentBlockIndex,
|
|
80
|
-
type: type,
|
|
81
|
-
content: '',
|
|
82
|
-
started: true,
|
|
83
|
-
stopped: false
|
|
84
|
-
};
|
|
85
|
-
this.contentBlocks.push(block);
|
|
86
|
-
|
|
87
|
-
// Reset buffer for new block (tool_use doesn't use buffers)
|
|
88
|
-
if (type === 'thinking') {
|
|
89
|
-
this.thinkingBuffer = '';
|
|
90
|
-
} else if (type === 'text') {
|
|
91
|
-
this.textBuffer = '';
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
return block;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
/**
|
|
98
|
-
* Add delta to current block
|
|
99
|
-
* @param {string} delta - Content delta
|
|
100
|
-
*/
|
|
101
|
-
addDelta(delta) {
|
|
102
|
-
const block = this.getCurrentBlock();
|
|
103
|
-
if (!block) {
|
|
104
|
-
// FIX: Guard against null block (should never happen, but defensive)
|
|
105
|
-
console.error('[DeltaAccumulator] ERROR: addDelta called with no current block');
|
|
106
|
-
return;
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
if (block.type === 'thinking') {
|
|
110
|
-
// C-02 Fix: Enforce buffer size limit
|
|
111
|
-
if (this.thinkingBuffer.length + delta.length > this.maxBufferSize) {
|
|
112
|
-
throw new Error(`Thinking buffer exceeded ${this.maxBufferSize} bytes (DoS protection)`);
|
|
113
|
-
}
|
|
114
|
-
this.thinkingBuffer += delta;
|
|
115
|
-
block.content = this.thinkingBuffer;
|
|
116
|
-
|
|
117
|
-
// FIX: Verify assignment succeeded (paranoid check for race conditions)
|
|
118
|
-
if (block.content.length !== this.thinkingBuffer.length) {
|
|
119
|
-
console.error('[DeltaAccumulator] ERROR: Block content assignment failed');
|
|
120
|
-
console.error(`Expected: ${this.thinkingBuffer.length}, Got: ${block.content.length}`);
|
|
121
|
-
}
|
|
122
|
-
} else if (block.type === 'text') {
|
|
123
|
-
// C-02 Fix: Enforce buffer size limit
|
|
124
|
-
if (this.textBuffer.length + delta.length > this.maxBufferSize) {
|
|
125
|
-
throw new Error(`Text buffer exceeded ${this.maxBufferSize} bytes (DoS protection)`);
|
|
126
|
-
}
|
|
127
|
-
this.textBuffer += delta;
|
|
128
|
-
block.content = this.textBuffer;
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
/**
|
|
133
|
-
* Mark current block as stopped
|
|
134
|
-
*/
|
|
135
|
-
stopCurrentBlock() {
|
|
136
|
-
const block = this.getCurrentBlock();
|
|
137
|
-
if (block) {
|
|
138
|
-
block.stopped = true;
|
|
139
|
-
|
|
140
|
-
// FIX: Log block closure for debugging (helps diagnose timing issues)
|
|
141
|
-
if (block.type === 'thinking' && process.env.CCS_DEBUG === '1') {
|
|
142
|
-
console.error(`[DeltaAccumulator] Stopped thinking block ${block.index}: ${block.content?.length || 0} chars`);
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
/**
|
|
148
|
-
* Update usage statistics
|
|
149
|
-
* @param {Object} usage - Usage object from OpenAI
|
|
150
|
-
*/
|
|
151
|
-
updateUsage(usage) {
|
|
152
|
-
if (usage) {
|
|
153
|
-
this.inputTokens = usage.prompt_tokens || usage.input_tokens || 0;
|
|
154
|
-
this.outputTokens = usage.completion_tokens || usage.output_tokens || 0;
|
|
155
|
-
this.usageReceived = true; // Mark that we've received usage data
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
/**
|
|
160
|
-
* Add or update tool call delta
|
|
161
|
-
* @param {Object} toolCallDelta - Tool call delta from OpenAI
|
|
162
|
-
*/
|
|
163
|
-
addToolCallDelta(toolCallDelta) {
|
|
164
|
-
const index = toolCallDelta.index;
|
|
165
|
-
|
|
166
|
-
// Initialize tool call if not exists
|
|
167
|
-
if (!this.toolCallsIndex[index]) {
|
|
168
|
-
const toolCall = {
|
|
169
|
-
index: index,
|
|
170
|
-
id: '',
|
|
171
|
-
type: 'function',
|
|
172
|
-
function: {
|
|
173
|
-
name: '',
|
|
174
|
-
arguments: ''
|
|
175
|
-
}
|
|
176
|
-
};
|
|
177
|
-
this.toolCalls.push(toolCall);
|
|
178
|
-
this.toolCallsIndex[index] = toolCall;
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
const toolCall = this.toolCallsIndex[index];
|
|
182
|
-
|
|
183
|
-
// Update id if present
|
|
184
|
-
if (toolCallDelta.id) {
|
|
185
|
-
toolCall.id = toolCallDelta.id;
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
// Update type if present
|
|
189
|
-
if (toolCallDelta.type) {
|
|
190
|
-
toolCall.type = toolCallDelta.type;
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
// Update function name if present
|
|
194
|
-
if (toolCallDelta.function?.name) {
|
|
195
|
-
toolCall.function.name += toolCallDelta.function.name;
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
// Update function arguments if present
|
|
199
|
-
if (toolCallDelta.function?.arguments) {
|
|
200
|
-
toolCall.function.arguments += toolCallDelta.function.arguments;
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
/**
|
|
205
|
-
* Get all tool calls
|
|
206
|
-
* @returns {Array} Tool calls array
|
|
207
|
-
*/
|
|
208
|
-
getToolCalls() {
|
|
209
|
-
return this.toolCalls;
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
/**
|
|
213
|
-
* Check for planning loop pattern
|
|
214
|
-
* Loop = N consecutive thinking blocks with no tool calls
|
|
215
|
-
* @returns {boolean} True if loop detected
|
|
216
|
-
*/
|
|
217
|
-
checkForLoop() {
|
|
218
|
-
// Already detected loop
|
|
219
|
-
if (this.loopDetected) {
|
|
220
|
-
return true;
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
// Need minimum blocks to detect pattern
|
|
224
|
-
if (this.contentBlocks.length < this.loopDetectionThreshold) {
|
|
225
|
-
return false;
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
// Get last N blocks
|
|
229
|
-
const recentBlocks = this.contentBlocks.slice(-this.loopDetectionThreshold);
|
|
230
|
-
|
|
231
|
-
// Check if all recent blocks are thinking blocks
|
|
232
|
-
const allThinking = recentBlocks.every(b => b.type === 'thinking');
|
|
233
|
-
|
|
234
|
-
// Check if no tool calls have been made at all
|
|
235
|
-
const noToolCalls = this.toolCalls.length === 0;
|
|
236
|
-
|
|
237
|
-
// Loop detected if: all recent blocks are thinking AND no tool calls yet
|
|
238
|
-
if (allThinking && noToolCalls) {
|
|
239
|
-
this.loopDetected = true;
|
|
240
|
-
return true;
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
return false;
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
/**
|
|
247
|
-
* Reset loop detection state (for testing)
|
|
248
|
-
*/
|
|
249
|
-
resetLoopDetection() {
|
|
250
|
-
this.loopDetected = false;
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
/**
|
|
254
|
-
* Get summary of accumulated state
|
|
255
|
-
* @returns {Object} Summary
|
|
256
|
-
*/
|
|
257
|
-
getSummary() {
|
|
258
|
-
return {
|
|
259
|
-
messageId: this.messageId,
|
|
260
|
-
model: this.model,
|
|
261
|
-
role: this.role,
|
|
262
|
-
blockCount: this.contentBlocks.length,
|
|
263
|
-
currentIndex: this.currentBlockIndex,
|
|
264
|
-
toolCallCount: this.toolCalls.length,
|
|
265
|
-
messageStarted: this.messageStarted,
|
|
266
|
-
finalized: this.finalized,
|
|
267
|
-
loopDetected: this.loopDetected,
|
|
268
|
-
usage: {
|
|
269
|
-
input_tokens: this.inputTokens,
|
|
270
|
-
output_tokens: this.outputTokens
|
|
271
|
-
}
|
|
272
|
-
};
|
|
273
|
-
}
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
module.exports = DeltaAccumulator;
|