@lightcone-ai/daemon 0.15.9 → 0.15.10

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.
@@ -457,16 +457,19 @@ server.tool(
457
457
  const adapter = await getAdapter(platform);
458
458
  return adapter.checkLoginStatus();
459
459
  });
460
+ // Always close session after login check so the Chrome profile is free
461
+ // for the daemon's publish job (which runs in a separate process)
462
+ closeSession(platform);
460
463
  if (loggedIn) {
461
464
  return { content: [{ type: 'text', text: `✓ ${label} 已登录,可以发布内容。` }] };
462
465
  } else {
463
- closeSession(platform);
464
466
  return {
465
467
  content: [{ type: 'text', text: `${label} 未登录或登录已过期。\n调试信息: url=${url}\nprofileDir=${profileDir}\n请在「连接外部账号」中重新扫码连接。` }],
466
468
  isError: true,
467
469
  };
468
470
  }
469
471
  } catch (err) {
472
+ closeSession(platform);
470
473
  return { content: [{ type: 'text', text: `检查失败: ${err.message}` }], isError: true };
471
474
  }
472
475
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lightcone-ai/daemon",
3
- "version": "0.15.9",
3
+ "version": "0.15.10",
4
4
  "type": "module",
5
5
  "main": "src/index.js",
6
6
  "bin": {
@@ -22,6 +22,12 @@ import { runRecordUrlNarrationTool } from './record-url-narration-tool.js';
22
22
  import { runSubmitToLibraryTool } from './submit-to-library-tool.js';
23
23
  import { isLeaseInvalidated, clearInvalidatedLease } from './governance-state.js';
24
24
  import { classifyLeaseWindow } from './lease-window.js';
25
+ import {
26
+ buildDirectApiHttpError,
27
+ buildDirectApiTransportError,
28
+ shouldEmitToolCallFailed,
29
+ toolCallFailedReason,
30
+ } from './tool-call-failure.js';
25
31
 
26
32
  const cliArgs = process.argv.slice(2);
27
33
  function getArg(name) {
@@ -528,17 +534,22 @@ function enqueueBundleEvent(eventType, payload = {}) {
528
534
 
529
535
  async function directApi(method, apiPath, body) {
530
536
  const url = `${SERVER_URL}/internal/agent/${AGENT_ID}${apiPath}`;
531
- const res = await fetch(url, {
532
- method,
533
- headers: {
534
- 'Content-Type': 'application/json',
535
- 'Authorization': `Bearer ${MACHINE_API_KEY}`,
536
- },
537
- body: body != null ? JSON.stringify(body) : undefined,
538
- });
537
+ let res;
538
+ try {
539
+ res = await fetch(url, {
540
+ method,
541
+ headers: {
542
+ 'Content-Type': 'application/json',
543
+ 'Authorization': `Bearer ${MACHINE_API_KEY}`,
544
+ },
545
+ body: body != null ? JSON.stringify(body) : undefined,
546
+ });
547
+ } catch (error) {
548
+ throw buildDirectApiTransportError({ method, apiPath, error });
549
+ }
539
550
  if (!res.ok) {
540
551
  const text = await res.text();
541
- throw new Error(`API ${method} ${apiPath} ${res.status}: ${text}`);
552
+ throw buildDirectApiHttpError({ method, apiPath, status: res.status, text });
542
553
  }
543
554
  return res.json();
544
555
  }
@@ -555,16 +566,21 @@ async function directApiVideoUpload(apiPath, {
555
566
  };
556
567
  if (filename) headers['X-File-Name'] = filename;
557
568
 
558
- const res = await fetch(url, {
559
- method: 'POST',
560
- headers,
561
- body: createReadStream(localPath),
562
- duplex: 'half',
563
- });
569
+ let res;
570
+ try {
571
+ res = await fetch(url, {
572
+ method: 'POST',
573
+ headers,
574
+ body: createReadStream(localPath),
575
+ duplex: 'half',
576
+ });
577
+ } catch (error) {
578
+ throw buildDirectApiTransportError({ method: 'POST', apiPath, error });
579
+ }
564
580
 
565
581
  if (!res.ok) {
566
582
  const text = await res.text();
567
- throw new Error(`API POST ${apiPath} ${res.status}: ${text}`);
583
+ throw buildDirectApiHttpError({ method: 'POST', apiPath, status: res.status, text });
568
584
  }
569
585
  return res.json();
570
586
  }
@@ -701,12 +717,14 @@ async function runMandatoryLocalTool({ toolName, toolInput = {}, executor }) {
701
717
  });
702
718
  return result;
703
719
  } catch (error) {
704
- enqueueBundleEvent('tool_call_failed', {
705
- trace_id: traceId,
706
- tool_name: toolName,
707
- tool_classification: classification,
708
- reason: error?.code ?? error?.message ?? 'unknown_error',
709
- });
720
+ if (shouldEmitToolCallFailed(error)) {
721
+ enqueueBundleEvent('tool_call_failed', {
722
+ trace_id: traceId,
723
+ tool_name: toolName,
724
+ tool_classification: classification,
725
+ reason: toolCallFailedReason(error),
726
+ });
727
+ }
710
728
  throw error;
711
729
  }
712
730
  }
@@ -854,12 +872,14 @@ async function api(method, apiPath, body) {
854
872
  });
855
873
  return data;
856
874
  } catch (err) {
857
- enqueueBundleEvent('tool_call_failed', {
858
- trace_id: traceId,
859
- tool_name: toolName,
860
- tool_classification: classification,
861
- reason: err?.code ?? err?.message ?? 'unknown_error',
862
- });
875
+ if (shouldEmitToolCallFailed(err)) {
876
+ enqueueBundleEvent('tool_call_failed', {
877
+ trace_id: traceId,
878
+ tool_name: toolName,
879
+ tool_classification: classification,
880
+ reason: toolCallFailedReason(err),
881
+ });
882
+ }
863
883
  throw err;
864
884
  }
865
885
  }
@@ -0,0 +1,26 @@
1
+ export function buildDirectApiTransportError({ method, apiPath, error }) {
2
+ const wrapped = new Error(`API ${method} ${apiPath} transport_error: ${error?.message ?? 'unknown_error'}`);
3
+ wrapped.code = error?.name === 'AbortError' ? 'timeout' : 'server_error';
4
+ wrapped.cause = error;
5
+ return wrapped;
6
+ }
7
+
8
+ export function buildDirectApiHttpError({ method, apiPath, status, text }) {
9
+ const error = new Error(`API ${method} ${apiPath} → ${status}: ${text}`);
10
+ error.status = status;
11
+ error.code = status >= 500 ? 'server_error' : 'api_client_error';
12
+ return error;
13
+ }
14
+
15
+ export function shouldEmitToolCallFailed(error) {
16
+ const status = Number(error?.status);
17
+ if (Number.isFinite(status) && status >= 400 && status < 500) return false;
18
+ if (error?.code === 'api_client_error') return false;
19
+ return true;
20
+ }
21
+
22
+ export function toolCallFailedReason(error) {
23
+ if (typeof error?.code === 'string' && error.code.trim()) return error.code.trim();
24
+ if (typeof error?.message === 'string' && error.message.trim()) return error.message.trim();
25
+ return 'unknown_error';
26
+ }