@lowdefy/server-dev 0.0.0-experimental-20260420104522 → 0.0.0-experimental-20260420135540

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lowdefy/server-dev",
3
- "version": "0.0.0-experimental-20260420104522",
3
+ "version": "0.0.0-experimental-20260420135540",
4
4
  "license": "Apache-2.0",
5
5
  "description": "",
6
6
  "homepage": "https://lowdefy.com",
@@ -36,34 +36,34 @@
36
36
  ".npmrc"
37
37
  ],
38
38
  "dependencies": {
39
- "@lowdefy/actions-core": "0.0.0-experimental-20260420104522",
40
- "@lowdefy/api": "0.0.0-experimental-20260420104522",
41
- "@lowdefy/block-utils": "0.0.0-experimental-20260420104522",
42
- "@lowdefy/blocks-aggrid": "0.0.0-experimental-20260420104522",
43
- "@lowdefy/blocks-antd": "0.0.0-experimental-20260420104522",
44
- "@lowdefy/blocks-antd-x": "0.0.0-experimental-20260420104522",
45
- "@lowdefy/blocks-basic": "0.0.0-experimental-20260420104522",
46
- "@lowdefy/blocks-echarts": "0.0.0-experimental-20260420104522",
47
- "@lowdefy/blocks-loaders": "0.0.0-experimental-20260420104522",
48
- "@lowdefy/blocks-markdown": "0.0.0-experimental-20260420104522",
49
- "@lowdefy/build": "0.0.0-experimental-20260420104522",
50
- "@lowdefy/client": "0.0.0-experimental-20260420104522",
51
- "@lowdefy/connection-axios-http": "0.0.0-experimental-20260420104522",
52
- "@lowdefy/engine": "0.0.0-experimental-20260420104522",
53
- "@lowdefy/errors": "0.0.0-experimental-20260420104522",
54
- "@lowdefy/helpers": "0.0.0-experimental-20260420104522",
55
- "@lowdefy/layout": "0.0.0-experimental-20260420104522",
56
- "@lowdefy/logger": "0.0.0-experimental-20260420104522",
57
- "@lowdefy/node-utils": "0.0.0-experimental-20260420104522",
58
- "@lowdefy/operators-change-case": "0.0.0-experimental-20260420104522",
59
- "@lowdefy/operators-dayjs": "0.0.0-experimental-20260420104522",
60
- "@lowdefy/operators-diff": "0.0.0-experimental-20260420104522",
61
- "@lowdefy/operators-js": "0.0.0-experimental-20260420104522",
62
- "@lowdefy/operators-mql": "0.0.0-experimental-20260420104522",
63
- "@lowdefy/operators-nunjucks": "0.0.0-experimental-20260420104522",
64
- "@lowdefy/operators-uuid": "0.0.0-experimental-20260420104522",
65
- "@lowdefy/operators-yaml": "0.0.0-experimental-20260420104522",
66
- "@lowdefy/plugin-next-auth": "0.0.0-experimental-20260420104522",
39
+ "@lowdefy/actions-core": "0.0.0-experimental-20260420135540",
40
+ "@lowdefy/api": "0.0.0-experimental-20260420135540",
41
+ "@lowdefy/block-utils": "0.0.0-experimental-20260420135540",
42
+ "@lowdefy/blocks-aggrid": "0.0.0-experimental-20260420135540",
43
+ "@lowdefy/blocks-antd": "0.0.0-experimental-20260420135540",
44
+ "@lowdefy/blocks-antd-x": "0.0.0-experimental-20260420135540",
45
+ "@lowdefy/blocks-basic": "0.0.0-experimental-20260420135540",
46
+ "@lowdefy/blocks-echarts": "0.0.0-experimental-20260420135540",
47
+ "@lowdefy/blocks-loaders": "0.0.0-experimental-20260420135540",
48
+ "@lowdefy/blocks-markdown": "0.0.0-experimental-20260420135540",
49
+ "@lowdefy/build": "0.0.0-experimental-20260420135540",
50
+ "@lowdefy/client": "0.0.0-experimental-20260420135540",
51
+ "@lowdefy/connection-axios-http": "0.0.0-experimental-20260420135540",
52
+ "@lowdefy/engine": "0.0.0-experimental-20260420135540",
53
+ "@lowdefy/errors": "0.0.0-experimental-20260420135540",
54
+ "@lowdefy/helpers": "0.0.0-experimental-20260420135540",
55
+ "@lowdefy/layout": "0.0.0-experimental-20260420135540",
56
+ "@lowdefy/logger": "0.0.0-experimental-20260420135540",
57
+ "@lowdefy/node-utils": "0.0.0-experimental-20260420135540",
58
+ "@lowdefy/operators-change-case": "0.0.0-experimental-20260420135540",
59
+ "@lowdefy/operators-dayjs": "0.0.0-experimental-20260420135540",
60
+ "@lowdefy/operators-diff": "0.0.0-experimental-20260420135540",
61
+ "@lowdefy/operators-js": "0.0.0-experimental-20260420135540",
62
+ "@lowdefy/operators-mql": "0.0.0-experimental-20260420135540",
63
+ "@lowdefy/operators-nunjucks": "0.0.0-experimental-20260420135540",
64
+ "@lowdefy/operators-uuid": "0.0.0-experimental-20260420135540",
65
+ "@lowdefy/operators-yaml": "0.0.0-experimental-20260420135540",
66
+ "@lowdefy/plugin-next-auth": "0.0.0-experimental-20260420135540",
67
67
  "@ant-design/cssinjs": "2.1.2",
68
68
  "antd": "6.3.1",
69
69
  "dayjs": "1.11.19",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lowdefy/server-dev",
3
- "version": "0.0.0-experimental-20260420104522",
3
+ "version": "0.0.0-experimental-20260420135540",
4
4
  "license": "Apache-2.0",
5
5
  "description": "",
6
6
  "homepage": "https://lowdefy.com",
@@ -44,34 +44,34 @@
44
44
  "prepublishOnly": "pnpm build"
45
45
  },
46
46
  "dependencies": {
47
- "@lowdefy/actions-core": "0.0.0-experimental-20260420104522",
48
- "@lowdefy/api": "0.0.0-experimental-20260420104522",
49
- "@lowdefy/block-utils": "0.0.0-experimental-20260420104522",
50
- "@lowdefy/blocks-aggrid": "0.0.0-experimental-20260420104522",
51
- "@lowdefy/blocks-antd": "0.0.0-experimental-20260420104522",
52
- "@lowdefy/blocks-antd-x": "0.0.0-experimental-20260420104522",
53
- "@lowdefy/blocks-basic": "0.0.0-experimental-20260420104522",
54
- "@lowdefy/blocks-echarts": "0.0.0-experimental-20260420104522",
55
- "@lowdefy/blocks-loaders": "0.0.0-experimental-20260420104522",
56
- "@lowdefy/blocks-markdown": "0.0.0-experimental-20260420104522",
57
- "@lowdefy/build": "0.0.0-experimental-20260420104522",
58
- "@lowdefy/client": "0.0.0-experimental-20260420104522",
59
- "@lowdefy/connection-axios-http": "0.0.0-experimental-20260420104522",
60
- "@lowdefy/engine": "0.0.0-experimental-20260420104522",
61
- "@lowdefy/errors": "0.0.0-experimental-20260420104522",
62
- "@lowdefy/helpers": "0.0.0-experimental-20260420104522",
63
- "@lowdefy/layout": "0.0.0-experimental-20260420104522",
64
- "@lowdefy/logger": "0.0.0-experimental-20260420104522",
65
- "@lowdefy/node-utils": "0.0.0-experimental-20260420104522",
66
- "@lowdefy/operators-change-case": "0.0.0-experimental-20260420104522",
67
- "@lowdefy/operators-dayjs": "0.0.0-experimental-20260420104522",
68
- "@lowdefy/operators-diff": "0.0.0-experimental-20260420104522",
69
- "@lowdefy/operators-js": "0.0.0-experimental-20260420104522",
70
- "@lowdefy/operators-mql": "0.0.0-experimental-20260420104522",
71
- "@lowdefy/operators-nunjucks": "0.0.0-experimental-20260420104522",
72
- "@lowdefy/operators-uuid": "0.0.0-experimental-20260420104522",
73
- "@lowdefy/operators-yaml": "0.0.0-experimental-20260420104522",
74
- "@lowdefy/plugin-next-auth": "0.0.0-experimental-20260420104522",
47
+ "@lowdefy/actions-core": "0.0.0-experimental-20260420135540",
48
+ "@lowdefy/api": "0.0.0-experimental-20260420135540",
49
+ "@lowdefy/block-utils": "0.0.0-experimental-20260420135540",
50
+ "@lowdefy/blocks-aggrid": "0.0.0-experimental-20260420135540",
51
+ "@lowdefy/blocks-antd": "0.0.0-experimental-20260420135540",
52
+ "@lowdefy/blocks-antd-x": "0.0.0-experimental-20260420135540",
53
+ "@lowdefy/blocks-basic": "0.0.0-experimental-20260420135540",
54
+ "@lowdefy/blocks-echarts": "0.0.0-experimental-20260420135540",
55
+ "@lowdefy/blocks-loaders": "0.0.0-experimental-20260420135540",
56
+ "@lowdefy/blocks-markdown": "0.0.0-experimental-20260420135540",
57
+ "@lowdefy/build": "0.0.0-experimental-20260420135540",
58
+ "@lowdefy/client": "0.0.0-experimental-20260420135540",
59
+ "@lowdefy/connection-axios-http": "0.0.0-experimental-20260420135540",
60
+ "@lowdefy/engine": "0.0.0-experimental-20260420135540",
61
+ "@lowdefy/errors": "0.0.0-experimental-20260420135540",
62
+ "@lowdefy/helpers": "0.0.0-experimental-20260420135540",
63
+ "@lowdefy/layout": "0.0.0-experimental-20260420135540",
64
+ "@lowdefy/logger": "0.0.0-experimental-20260420135540",
65
+ "@lowdefy/node-utils": "0.0.0-experimental-20260420135540",
66
+ "@lowdefy/operators-change-case": "0.0.0-experimental-20260420135540",
67
+ "@lowdefy/operators-dayjs": "0.0.0-experimental-20260420135540",
68
+ "@lowdefy/operators-diff": "0.0.0-experimental-20260420135540",
69
+ "@lowdefy/operators-js": "0.0.0-experimental-20260420135540",
70
+ "@lowdefy/operators-mql": "0.0.0-experimental-20260420135540",
71
+ "@lowdefy/operators-nunjucks": "0.0.0-experimental-20260420135540",
72
+ "@lowdefy/operators-uuid": "0.0.0-experimental-20260420135540",
73
+ "@lowdefy/operators-yaml": "0.0.0-experimental-20260420135540",
74
+ "@lowdefy/plugin-next-auth": "0.0.0-experimental-20260420135540",
75
75
  "@ant-design/cssinjs": "2.1.2",
76
76
  "antd": "6.3.1",
77
77
  "dayjs": "1.11.19",
@@ -14,7 +14,10 @@
14
14
  limitations under the License.
15
15
  */
16
16
 
17
+ import crypto from 'crypto';
18
+
17
19
  import { callAgent } from '@lowdefy/api';
20
+ import { createPhaseLogger } from '@lowdefy/ai-utils';
18
21
  import { type } from '@lowdefy/helpers';
19
22
 
20
23
  import apiWrapper from '../../../lib/server/apiWrapper.js';
@@ -32,7 +35,7 @@ async function handler({ context, req, res }) {
32
35
  const pageId = segments.slice(0, -1).join('/');
33
36
  context.logger.info({ color: 'gray' }, `Agent: ${pageId} → ${agentId}`);
34
37
  const { conversationId } = req.query;
35
- const { messages, urlQuery, sharedState } = req.body;
38
+ const { messages, urlQuery, sharedState, turnId: clientTurnId } = req.body;
36
39
  if (!Array.isArray(messages)) {
37
40
  res.status(400).json({ error: 'messages must be an array' });
38
41
  return;
@@ -45,6 +48,37 @@ async function handler({ context, req, res }) {
45
48
  res.status(400).json({ error: 'sharedState must be an object' });
46
49
  return;
47
50
  }
51
+
52
+ const turnId =
53
+ typeof clientTurnId === 'string' && clientTurnId ? clientTurnId : crypto.randomUUID();
54
+ const turnStart = Date.now();
55
+ const phaseLogger = createPhaseLogger({
56
+ logger: context.logger,
57
+ agentId,
58
+ pageId,
59
+ conversationId: conversationId ?? undefined,
60
+ turnId,
61
+ turnStart,
62
+ });
63
+
64
+ const bodySize = (() => {
65
+ try {
66
+ return Buffer.byteLength(JSON.stringify(req.body ?? ''));
67
+ } catch {
68
+ return -1;
69
+ }
70
+ })();
71
+ const hasFiles = Array.isArray(messages)
72
+ ? messages.some((m) => (m?.parts ?? []).some((p) => p?.type === 'file'))
73
+ : false;
74
+ phaseLogger.phase('ingress.received', {
75
+ bodySize,
76
+ messageCount: messages.length,
77
+ hasFiles,
78
+ sharedStateKeys: sharedState ? Object.keys(sharedState).length : 0,
79
+ urlQueryKeys: urlQuery ? Object.keys(urlQuery).length : 0,
80
+ });
81
+
48
82
  const { response: webResponse } = await callAgent(context, {
49
83
  agentId,
50
84
  pageId,
@@ -52,6 +86,8 @@ async function handler({ context, req, res }) {
52
86
  conversationId: conversationId ?? undefined,
53
87
  sharedState: sharedState ?? undefined,
54
88
  urlQuery: urlQuery ?? undefined,
89
+ phaseLogger,
90
+ turnId,
55
91
  });
56
92
 
57
93
  // Stream the Web Response body to the Next.js response
@@ -61,17 +97,29 @@ async function handler({ context, req, res }) {
61
97
  res.setHeader('Content-Encoding', 'none');
62
98
  res.setHeader('Transfer-Encoding', 'chunked');
63
99
 
100
+ phaseLogger.phase('ingress.stream.forward.start');
101
+
64
102
  const reader = webResponse.body.getReader();
65
103
  const decoder = new TextDecoder();
66
104
  let done = false;
105
+ let firstByteLogged = false;
106
+ let chunkCount = 0;
107
+ let totalBytes = 0;
67
108
  while (!done) {
68
109
  const { value, done: readerDone } = await reader.read();
69
110
  done = readerDone;
70
111
  if (value) {
112
+ if (!firstByteLogged) {
113
+ firstByteLogged = true;
114
+ phaseLogger.phase('ingress.stream.first_byte', { bytes: value.byteLength });
115
+ }
116
+ chunkCount += 1;
117
+ totalBytes += value.byteLength;
71
118
  res.write(decoder.decode(value, { stream: true }));
72
119
  }
73
120
  }
74
121
  res.end();
122
+ phaseLogger.phase('ingress.stream.forward.done', { chunkCount, totalBytes });
75
123
  }
76
124
 
77
125
  export const config = {