yaml-flow 5.2.8 → 5.3.0
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/browser/board-livegraph-engine.js +4 -1
- package/browser/board-livegraph-engine.js.map +1 -1
- package/browser/card-compute.js +1 -1
- package/browser/live-cards.js +178 -144
- package/browser/live-cards.schema.json +1 -1
- package/dist/board-livegraph-runtime/index.cjs +4 -1
- package/dist/board-livegraph-runtime/index.cjs.map +1 -1
- package/dist/board-livegraph-runtime/index.js +4 -1
- package/dist/board-livegraph-runtime/index.js.map +1 -1
- package/dist/card-compute/index.cjs +5 -1
- package/dist/card-compute/index.cjs.map +1 -1
- package/dist/card-compute/index.js +5 -1
- package/dist/card-compute/index.js.map +1 -1
- package/dist/cli/board-live-cards-cli.cjs +5 -1
- package/dist/cli/board-live-cards-cli.cjs.map +1 -1
- package/dist/cli/board-live-cards-cli.js +5 -1
- package/dist/cli/board-live-cards-cli.js.map +1 -1
- package/dist/continuous-event-graph/index.cjs +4 -1
- package/dist/continuous-event-graph/index.cjs.map +1 -1
- package/dist/continuous-event-graph/index.js +4 -1
- package/dist/continuous-event-graph/index.js.map +1 -1
- package/dist/index.cjs +5 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +5 -1
- package/dist/index.js.map +1 -1
- package/examples/example-board/agent-instructions-cardlayout.md +28 -0
- package/examples/example-board/cards/card-rebalance-sim.json +13 -3
- package/examples/example-board/demo-server.js +20 -8
- package/examples/example-board/demo-shell-browser.html +3 -3
- package/examples/example-board/demo-shell-with-server.html +4 -4
- package/examples/example-board/demo-task-executor.js +21 -0
- package/package.json +1 -1
- package/schema/live-cards.schema.json +1 -1
|
@@ -26,3 +26,31 @@
|
|
|
26
26
|
- `board.col` — Bootstrap 12-column span: `3`=quarter, `4`=third, `6`=half, `8`=two-thirds, `12`=full
|
|
27
27
|
- `board.order` — ascending integer, controls vertical sort in board view
|
|
28
28
|
- `canvas` — pixel coordinates/size for drag-layout (canvas mode). `h` must be tall enough for all rendered content — a card with metrics + a 4-row table typically needs 400–500px. Too small a height causes an in-card scrollbar; when in doubt, size generously.
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
## LLM View-Type Guidance (for `kind: "ref"`)
|
|
33
|
+
|
|
34
|
+
When a source uses Copilot/LLM and the card renders via a `ref` element, the model should emit a `_view` hint alongside the data.
|
|
35
|
+
|
|
36
|
+
- Keep `_view.kind` within the renderer whitelist only:
|
|
37
|
+
`table`, `editable-table`, `chart`, `metric`, `list`, `badge`, `text`, `narrative`, `markdown`, `form`, `filter`, `todo`, `alert`
|
|
38
|
+
- Default to `table` when uncertain.
|
|
39
|
+
- Use `editable-table` for user-adjustable tabular rows and include `data.writeTo` to a `card_data` path.
|
|
40
|
+
- Use `chart` only when one clear category/value mapping exists; include `data.chartType` and `data.columns: [labelField, valueField]`.
|
|
41
|
+
- Keep `_view.data` minimal. Static card JSON may override it for safety.
|
|
42
|
+
|
|
43
|
+
Recommended response shape:
|
|
44
|
+
|
|
45
|
+
```json
|
|
46
|
+
{
|
|
47
|
+
"<data_key>": [ ... ],
|
|
48
|
+
"_view": {
|
|
49
|
+
"kind": "editable-table",
|
|
50
|
+
"data": {
|
|
51
|
+
"writeTo": "card_data.<key>",
|
|
52
|
+
"columns": ["field1", "field2"]
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
```
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
"portfolio_action": "requires.portfolio_action"
|
|
20
20
|
},
|
|
21
21
|
"copilot": {
|
|
22
|
-
"prompt_template": "You are a portfolio rebalance advisor. Using the intelligence analysis and current holdings below, propose specific trades.\n\nCurrent holdings:\n{{holdings}}\nFields: ticker, quantity, cost_basis ($).\n\nPositions (with live prices):\n{{positions}}\nFields: ticker, quantity, cost_basis, price ($), value ($), gain_$, gain_%, chg_$, chg_pct.\n\nPortfolio intelligence:\n- Mix: {{portfolio_mix}}\n- Risks: {{portfolio_risks}}\n- Action signal: {{portfolio_action}}\n\nIMPORTANT OUTPUT RULES:\n- Return ONLY a valid JSON object. No markdown, no preamble, no trailing text.\n- Start with { and end with }.\n- proposed_trades must be an array of objects with EXACTLY these fields per entry:\n ticker (string), direction (\"reduce\" or \"increase\"), current_qty (number, current shares held), change (number, shares to trade), proposed_qty (number, resulting shares after trade), price (number, current price per share), trade_value (number, change * price rounded to 2 decimals), reason (string, one short sentence).\n- Include one entry per ticker you recommend changing. Do not include tickers with no change.\n\n{\n \"proposed_trades\": [\n {\"ticker\": \"AAPL\", \"direction\": \"reduce\", \"current_qty\": 15, \"change\": 5, \"proposed_qty\": 10, \"price\": 210.50, \"trade_value\": 1052.50, \"reason\": \"overweight at 41%, trim before earnings\"}\n ]\n}"
|
|
22
|
+
"prompt_template": "You are a portfolio rebalance advisor. Using the intelligence analysis and current holdings below, propose specific trades.\n\nCurrent holdings:\n{{holdings}}\nFields: ticker, quantity, cost_basis ($).\n\nPositions (with live prices):\n{{positions}}\nFields: ticker, quantity, cost_basis, price ($), value ($), gain_$, gain_%, chg_$, chg_pct.\n\nPortfolio intelligence:\n- Mix: {{portfolio_mix}}\n- Risks: {{portfolio_risks}}\n- Action signal: {{portfolio_action}}\n\n{{view_kind_guidance}}\n\n{{card_layout_guidance}}\n\nIMPORTANT OUTPUT RULES:\n- Return ONLY a valid JSON object. No markdown, no preamble, no trailing text.\n- Start with { and end with }.\n- proposed_trades must be an array of objects with EXACTLY these fields per entry:\n ticker (string), direction (\"reduce\" or \"increase\"), current_qty (number, current shares held), change (number, shares to trade), proposed_qty (number, resulting shares after trade), price (number, current price per share), trade_value (number, change * price rounded to 2 decimals), reason (string, one short sentence).\n- Include one entry per ticker you recommend changing. Do not include tickers with no change.\n- Include a top-level _view object for a ref element with this shape:\n { \"kind\": \"editable-table\"|\"table\"|\"chart\", \"data\": { ... } }\n- If kind is editable-table or table, include data.columns with the exact proposed_trades fields in desired order.\n- If kind is editable-table, also include data.writeTo = \"card_data.proposed_trades\".\n- If kind is chart, include data.chartType and data.columns as [\"ticker\", \"trade_value\"].\n- If unsure, choose editable-table.\n\n{\n \"proposed_trades\": [\n {\"ticker\": \"AAPL\", \"direction\": \"reduce\", \"current_qty\": 15, \"change\": 5, \"proposed_qty\": 10, \"price\": 210.50, \"trade_value\": 1052.50, \"reason\": \"overweight at 41%, trim before earnings\"}\n ],\n \"_view\": {\n \"kind\": \"editable-table\",\n \"data\": {\n \"writeTo\": \"card_data.proposed_trades\",\n \"columns\": [\"ticker\", \"direction\", \"current_qty\", \"change\", \"proposed_qty\", \"price\", \"trade_value\", \"reason\"]\n }\n }\n}"
|
|
23
23
|
}
|
|
24
24
|
}
|
|
25
25
|
],
|
|
@@ -29,10 +29,12 @@
|
|
|
29
29
|
"view": {
|
|
30
30
|
"elements": [
|
|
31
31
|
{
|
|
32
|
-
"kind": "
|
|
32
|
+
"kind": "ref",
|
|
33
33
|
"label": "Proposed Trades",
|
|
34
34
|
"data": {
|
|
35
35
|
"bind": "fetched_sources.rebalance.proposed_trades",
|
|
36
|
+
"viewBind": "fetched_sources.rebalance._view",
|
|
37
|
+
"fallbackKind": "editable-table",
|
|
36
38
|
"writeTo": "card_data.proposed_trades",
|
|
37
39
|
"columns": ["ticker", "direction", "current_qty", "change", "proposed_qty", "price", "trade_value", "reason"],
|
|
38
40
|
"schema": {
|
|
@@ -45,13 +47,21 @@
|
|
|
45
47
|
}
|
|
46
48
|
}
|
|
47
49
|
}
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
"kind": "notes",
|
|
53
|
+
"label": "Notes",
|
|
54
|
+
"data": {
|
|
55
|
+
"bind": "card_data.notes",
|
|
56
|
+
"writeTo": "card_data.notes"
|
|
57
|
+
}
|
|
48
58
|
}
|
|
49
59
|
],
|
|
50
60
|
"layout": {
|
|
51
61
|
"board": { "col": 6, "order": 7 },
|
|
52
62
|
"canvas": { "x": 840, "y": 480, "w": 500, "h": 280 }
|
|
53
63
|
},
|
|
54
|
-
"features": { "refresh": true
|
|
64
|
+
"features": { "refresh": true }
|
|
55
65
|
},
|
|
56
66
|
"card_data": {}
|
|
57
67
|
}
|
|
@@ -168,26 +168,38 @@ async function handleWorkiqAsk(req, res) {
|
|
|
168
168
|
await new Promise((resolve) => {
|
|
169
169
|
let stdout = '';
|
|
170
170
|
let stderr = '';
|
|
171
|
+
let responded = false;
|
|
171
172
|
const child = spawn(process.execPath, [workiqJs, 'ask', '-q', query], {
|
|
172
173
|
stdio: ['inherit', 'pipe', 'pipe'],
|
|
173
174
|
});
|
|
174
175
|
child.stdout.on('data', chunk => { stdout += chunk; });
|
|
175
176
|
child.stderr.on('data', chunk => { stderr += chunk; });
|
|
176
177
|
child.on('error', (err) => {
|
|
177
|
-
|
|
178
|
+
if (!responded) {
|
|
179
|
+
responded = true;
|
|
180
|
+
clearTimeout(timeoutId);
|
|
181
|
+
jsonReply(res, 500, { error: `workiq spawn error: ${err.message}` });
|
|
182
|
+
}
|
|
178
183
|
resolve();
|
|
179
184
|
});
|
|
180
185
|
child.on('close', (code) => {
|
|
181
|
-
if (
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
186
|
+
if (!responded) {
|
|
187
|
+
responded = true;
|
|
188
|
+
clearTimeout(timeoutId);
|
|
189
|
+
if (code !== 0) {
|
|
190
|
+
jsonReply(res, 500, { error: `workiq exited ${code}`, stderr });
|
|
191
|
+
} else {
|
|
192
|
+
jsonReply(res, 200, { response: stdout });
|
|
193
|
+
}
|
|
185
194
|
}
|
|
186
195
|
resolve();
|
|
187
196
|
});
|
|
188
|
-
setTimeout(() => {
|
|
189
|
-
|
|
190
|
-
|
|
197
|
+
const timeoutId = setTimeout(() => {
|
|
198
|
+
if (!responded) {
|
|
199
|
+
responded = true;
|
|
200
|
+
child.kill();
|
|
201
|
+
jsonReply(res, 504, { error: 'workiq timed out after 60s' });
|
|
202
|
+
}
|
|
191
203
|
resolve();
|
|
192
204
|
}, 60_000);
|
|
193
205
|
});
|
|
@@ -6,9 +6,9 @@
|
|
|
6
6
|
<title>Example Board Demo (Browser Runtime)</title>
|
|
7
7
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" />
|
|
8
8
|
<script src="https://cdn.jsdelivr.net/npm/jsonata/jsonata.min.js"></script>
|
|
9
|
-
<script src="https://cdn.jsdelivr.net/npm/yaml-flow@5.
|
|
10
|
-
<script src="https://cdn.jsdelivr.net/npm/yaml-flow@5.
|
|
11
|
-
<script src="https://cdn.jsdelivr.net/npm/yaml-flow@5.
|
|
9
|
+
<script src="https://cdn.jsdelivr.net/npm/yaml-flow@5.3.0/browser/card-compute.js"></script>
|
|
10
|
+
<script src="https://cdn.jsdelivr.net/npm/yaml-flow@5.3.0/browser/live-cards.js"></script>
|
|
11
|
+
<script src="https://cdn.jsdelivr.net/npm/yaml-flow@5.3.0/browser/board-livegraph-engine.js"></script>
|
|
12
12
|
</head>
|
|
13
13
|
<body class="bg-light">
|
|
14
14
|
<div class="container-fluid py-3">
|
|
@@ -16,10 +16,10 @@
|
|
|
16
16
|
</style>
|
|
17
17
|
<script src="https://cdn.jsdelivr.net/npm/jsonata/jsonata.min.js"></script>
|
|
18
18
|
<script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
|
|
19
|
-
<script src="https://cdn.jsdelivr.net/npm/yaml-flow@5.
|
|
20
|
-
<script src="https://cdn.jsdelivr.net/npm/yaml-flow@5.
|
|
21
|
-
<script src="https://cdn.jsdelivr.net/npm/yaml-flow@5.
|
|
22
|
-
<script src="https://cdn.jsdelivr.net/npm/yaml-flow@5.
|
|
19
|
+
<script src="https://cdn.jsdelivr.net/npm/yaml-flow@5.3.0/browser/card-compute.js"></script>
|
|
20
|
+
<script src="https://cdn.jsdelivr.net/npm/yaml-flow@5.3.0/browser/live-cards.js"></script>
|
|
21
|
+
<script src="https://cdn.jsdelivr.net/npm/yaml-flow@5.3.0/browser/board-livegraph-engine.js"></script>
|
|
22
|
+
<script src="https://cdn.jsdelivr.net/npm/yaml-flow@5.3.0/browser/board-livecards-runtime-client.js"></script>
|
|
23
23
|
</head>
|
|
24
24
|
<body class="bg-light">
|
|
25
25
|
<div class="container-fluid py-3">
|
|
@@ -137,6 +137,26 @@ function interpolatePrompt(template, args) {
|
|
|
137
137
|
});
|
|
138
138
|
}
|
|
139
139
|
|
|
140
|
+
// Reusable prompt fragments available to all copilot source templates.
|
|
141
|
+
// Source definitions can interpolate them with {{view_kind_guidance}} and {{card_layout_guidance}}.
|
|
142
|
+
const COPILOT_PROMPT_CONTEXT = {
|
|
143
|
+
view_kind_guidance: [
|
|
144
|
+
'VIEW KIND GUIDANCE (for dynamic ref rendering):',
|
|
145
|
+
'- Return a _view object whenever your output data is meant for a ref element.',
|
|
146
|
+
'- Allowed _view.kind values only: table, editable-table, chart, metric, list, badge, text, narrative, markdown, form, filter, todo, alert.',
|
|
147
|
+
'- If uncertain, use "table".',
|
|
148
|
+
'- For array rows that users should edit, prefer "editable-table" and set _view.data.writeTo to a card_data path.',
|
|
149
|
+
'- For chart, set _view.data.chartType and _view.data.columns with [labelField, valueField].',
|
|
150
|
+
'- Keep _view.data minimal and valid JSON (no comments, no trailing text).',
|
|
151
|
+
].join('\n'),
|
|
152
|
+
card_layout_guidance: [
|
|
153
|
+
'CARD LAYOUT GUIDANCE:',
|
|
154
|
+
'- Prefer compact outputs that fit a card: one primary structure plus concise rationale text.',
|
|
155
|
+
'- Avoid repeating values already present in upstream inputs.',
|
|
156
|
+
'- If you produce both machine-readable and human-readable content, keep machine-readable fields top-level and concise prose in a separate field.',
|
|
157
|
+
].join('\n'),
|
|
158
|
+
};
|
|
159
|
+
|
|
140
160
|
/**
|
|
141
161
|
* Fetch a URL using the system curl binary (synchronous, no Node event-loop handles).
|
|
142
162
|
* Throws if curl exits non-zero (e.g. HTTP 4xx/5xx with -f, or network error).
|
|
@@ -167,6 +187,7 @@ function resolveCopilotPrompt(sourceDef) {
|
|
|
167
187
|
// evaluated by the engine from card_data/requires before invoking this executor.
|
|
168
188
|
// Explicit args defined on the source take highest precedence.
|
|
169
189
|
const interpolationContext = {
|
|
190
|
+
...COPILOT_PROMPT_CONTEXT,
|
|
170
191
|
...sourceDef._projections,
|
|
171
192
|
...args,
|
|
172
193
|
};
|
package/package.json
CHANGED
|
@@ -126,7 +126,7 @@
|
|
|
126
126
|
"kind": {
|
|
127
127
|
"enum": ["metric", "table", "editable-table", "chart", "form", "filter", "list",
|
|
128
128
|
"notes", "todo", "alert", "narrative", "badge", "text",
|
|
129
|
-
"markdown", "custom", "actions"]
|
|
129
|
+
"markdown", "ref", "custom", "actions"]
|
|
130
130
|
},
|
|
131
131
|
"label": { "type": "string", "description": "Heading above this element" },
|
|
132
132
|
"className": { "type": "string", "description": "Bootstrap grid class, e.g. 'col-12 col-md-6'" },
|