gpteam 0.1.30 → 0.1.32

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/lib/bench.js CHANGED
@@ -118,15 +118,7 @@ function measureStream(baseUrl, options) {
118
118
  const url = new URL(`${baseUrl.replace(/\/$/, '')}/responses`);
119
119
  const started = performance.now();
120
120
  const timings = { dnsMs: NaN, tcpMs: NaN, tlsMs: NaN, firstEventMs: NaN };
121
- const payload = JSON.stringify({
122
- model: options.model,
123
- stream: true,
124
- instructions: 'You are a helpful coding assistant.',
125
- input: options.prompt || '请只回复一句话:节点测速完成。',
126
- max_output_tokens: options.maxOutputTokens || 648,
127
- reasoning: options.effort ? { effort: options.effort } : undefined,
128
- metadata: { gpteam_config_probe: '1' }
129
- });
121
+ const payload = JSON.stringify(buildResponsesProbePayload(options));
130
122
 
131
123
  const request = https.request({
132
124
  protocol: url.protocol,
@@ -198,6 +190,21 @@ function measureStream(baseUrl, options) {
198
190
  });
199
191
  }
200
192
 
193
+ export function buildResponsesProbePayload(options = {}) {
194
+ const prompt = options.prompt || '请只回复一句话:节点测速完成。';
195
+ return {
196
+ model: options.model,
197
+ stream: true,
198
+ instructions: 'You are a helpful coding assistant.',
199
+ input: [{
200
+ role: 'user',
201
+ content: [{ type: 'input_text', text: prompt }]
202
+ }],
203
+ reasoning: options.effort ? { effort: options.effort } : undefined,
204
+ metadata: { gpteam_config_probe: '1' }
205
+ };
206
+ }
207
+
201
208
  export function formatStreamProbeError(status, headers, body, semanticError) {
202
209
  const statusCode = Number(status || 0);
203
210
  const contentType = String(headers?.['content-type'] || headers?.['Content-Type'] || '').trim();
package/lib/config.js CHANGED
@@ -59,9 +59,9 @@ export function writeCodexConfig(settings) {
59
59
  'requires_openai_auth = true',
60
60
  'supports_websockets = true'
61
61
  ];
62
- const websocketFeature = settings.websocket === true
63
- ? ['[features]', 'responses_websockets_v2 = true']
64
- : [];
62
+ const restWithFeatures = mergeCodexFeatureLines(rest, {
63
+ responses_websockets_v2: settings.websocket === true ? 'true' : null
64
+ });
65
65
  const mcpCommand = codexImageMCPCommand();
66
66
  const mcpEnv = imageMCPEnv(settings);
67
67
  const managedImageMCP = [
@@ -82,8 +82,7 @@ export function writeCodexConfig(settings) {
82
82
  const next = joinTomlSections([
83
83
  managedRoot.join('\n'),
84
84
  rootLines.join('\n'),
85
- rest.join('\n'),
86
- websocketFeature.join('\n'),
85
+ restWithFeatures.join('\n'),
87
86
  imageMCPEnabled(settings) ? managedImageMCP.join('\n') : '',
88
87
  managedProvider.join('\n')
89
88
  ]);
@@ -520,11 +519,16 @@ function joinTomlSections(sections) {
520
519
 
521
520
  function assertNoDuplicateTomlKeys(text) {
522
521
  const seen = new Map();
522
+ const seenTables = new Set();
523
523
  let section = '<root>';
524
524
  for (const line of String(text || '').split(/\r?\n/)) {
525
525
  const table = line.match(/^\s*\[([^\]]+)\]\s*$/);
526
526
  if (table) {
527
527
  section = table[1];
528
+ if (seenTables.has(section)) {
529
+ throw new Error(`生成的 Codex 配置存在重复表:${section},已停止写入`);
530
+ }
531
+ seenTables.add(section);
528
532
  if (!seen.has(section)) seen.set(section, new Set());
529
533
  continue;
530
534
  }
@@ -566,10 +570,59 @@ function isManagedProviderLine(line) {
566
570
  return /^\s*(name|base_url|wire_api|requires_openai_auth|supports_websockets)\s*=/.test(line);
567
571
  }
568
572
 
573
+ function isFeaturesHeader(line) {
574
+ return /^\s*\[features\]\s*$/.test(line);
575
+ }
576
+
577
+ function isManagedFeatureLine(line) {
578
+ return /^\s*responses_websockets_v2\s*=/.test(line);
579
+ }
580
+
569
581
  function isSalvageableRootLine(line) {
570
582
  return /^\s*(js_repl_node_path|preferred_auth_method|personality|plan_mode_reasoning_effort|service_tier)\s*=/.test(line);
571
583
  }
572
584
 
585
+ function mergeCodexFeatureLines(lines, features) {
586
+ const featureLines = Object.entries(features || {})
587
+ .filter(([, value]) => value !== null && value !== undefined)
588
+ .map(([key, value]) => `${key} = ${value}`);
589
+ const out = [];
590
+ let inFeatures = false;
591
+ let featuresTableSeen = false;
592
+ let managedLinesInserted = false;
593
+
594
+ for (const line of lines) {
595
+ if (isTableHeader(line)) {
596
+ if (inFeatures && !managedLinesInserted) {
597
+ appendManagedFeatureLines(out, featureLines);
598
+ if (out.length && out[out.length - 1].trim()) out.push('');
599
+ managedLinesInserted = true;
600
+ }
601
+ inFeatures = isFeaturesHeader(line);
602
+ if (inFeatures) featuresTableSeen = true;
603
+ out.push(line);
604
+ continue;
605
+ }
606
+ if (inFeatures && isManagedFeatureLine(line)) continue;
607
+ out.push(line);
608
+ }
609
+
610
+ if (inFeatures && !managedLinesInserted) {
611
+ appendManagedFeatureLines(out, featureLines);
612
+ managedLinesInserted = true;
613
+ }
614
+ if (!featuresTableSeen && featureLines.length > 0) {
615
+ if (out.length && out[out.length - 1].trim()) out.push('');
616
+ out.push('[features]', ...featureLines);
617
+ }
618
+ return trimEmptyEdges(out);
619
+ }
620
+
621
+ function appendManagedFeatureLines(out, featureLines) {
622
+ while (out.length && !out[out.length - 1].trim()) out.pop();
623
+ out.push(...featureLines);
624
+ }
625
+
573
626
  function backupIfExists(filePath) {
574
627
  if (!fs.existsSync(filePath)) return;
575
628
  const stamp = new Date().toISOString().replace(/[-:]/g, '').replace(/\..+/, '').replace('T', '-');
package/lib/help.js CHANGED
@@ -1,5 +1,5 @@
1
1
  export const PACKAGE_NAME = 'gpteam';
2
- export const PACKAGE_VERSION = '0.1.30';
2
+ export const PACKAGE_VERSION = '0.1.32';
3
3
 
4
4
  export function getHelpText() {
5
5
  return [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gpteam",
3
- "version": "0.1.30",
3
+ "version": "0.1.32",
4
4
  "description": "GPTEAM API interactive client configurator and ingress benchmark CLI.",
5
5
  "type": "module",
6
6
  "bin": {