@llamaventures/cli 2.1.2 → 2.2.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/AGENT_BRIEFING.md +22 -8
- package/CHANGELOG.md +22 -0
- package/README.md +9 -5
- package/README.zh-CN.md +8 -3
- package/bin/llama-mcp.mjs +25 -3
- package/bin/llama.mjs +56 -6
- package/contracts/core-api.json +4 -4
- package/contracts/required-operations.json +1 -0
- package/lib/build-manifest.json +4 -4
- package/lib/deal-actions.mjs +71 -0
- package/lib/page-schema.mjs +24 -0
- package/package.json +2 -2
package/AGENT_BRIEFING.md
CHANGED
|
@@ -15,9 +15,12 @@ llama agent bootstrap
|
|
|
15
15
|
The authenticated response contains the current private Llama Brain with
|
|
16
16
|
exactly two components: the approved Investment Framework V3 Markdown (how to
|
|
17
17
|
think) and the Llama Command operating skill (how to work). Beside Brain it
|
|
18
|
-
contains the
|
|
19
|
-
|
|
20
|
-
|
|
18
|
+
contains a compact index of the current Live Deal Page fields. Before
|
|
19
|
+
`page.patch`, progressively load only the exact fields being changed with
|
|
20
|
+
`llama page-schema read <field> [field...]` or `get_live_deal_page_schema`.
|
|
21
|
+
Load one section only when the write genuinely spans that section. The public
|
|
22
|
+
CLI intentionally bundles none of this private content; it only fetches it
|
|
23
|
+
after authentication.
|
|
21
24
|
|
|
22
25
|
CLI is the Agent's tool, not Brain. Do not substitute a private skill wrapper
|
|
23
26
|
for either canonical Brain component.
|
|
@@ -60,7 +63,7 @@ judgment with its author; otherwise label the value as an Agent proposal / 待
|
|
|
60
63
|
replace the entire array. Before changing one `whatTheyDo`, `peopleSteps`,
|
|
61
64
|
`foundersJson`, or `industryMaps` item, read the current Page, preserve every
|
|
62
65
|
sibling item, and submit the complete updated array. The live field contract
|
|
63
|
-
|
|
66
|
+
read for those exact fields includes their payload paths and write modes.
|
|
64
67
|
|
|
65
68
|
## Exactly four Deal actions
|
|
66
69
|
|
|
@@ -159,16 +162,27 @@ Always submit raw user information first when losing it would be unacceptable:
|
|
|
159
162
|
}
|
|
160
163
|
```
|
|
161
164
|
|
|
162
|
-
Then, when useful, write a structured Information unit
|
|
165
|
+
Then, when useful, write a structured Information unit. Before each one, ask a
|
|
166
|
+
single question: is this a Llama user's own subjective judgment? Subjective
|
|
167
|
+
means the truth depends on who judges: a value or comparative word with no
|
|
168
|
+
stated benchmark, or a claim about someone's future behavior or inner state. If
|
|
169
|
+
yes, the type is `human_subjective_view.people` (founders or team) or
|
|
170
|
+
`human_subjective_view.business` (company, product, market or deal),
|
|
171
|
+
`value.speaker` names that user, and `value.rawText` quotes the user verbatim
|
|
172
|
+
from `origin.originalUserUtterance`. CLI and Core reject anything else. If no,
|
|
173
|
+
choose any type that fits; founder words are `founder_claim`.
|
|
163
174
|
|
|
164
175
|
```json
|
|
165
176
|
{
|
|
166
177
|
"operation": "information.put",
|
|
167
178
|
"dealId": "<uuid>",
|
|
168
|
-
"type": "
|
|
169
|
-
"labels": ["human_view"],
|
|
179
|
+
"type": "human_subjective_view.people",
|
|
170
180
|
"subject": {"person": "Founder name"},
|
|
171
|
-
"value": {
|
|
181
|
+
"value": {
|
|
182
|
+
"speaker": "<Llama user>",
|
|
183
|
+
"rawText": "I think the founder has strong product taste.",
|
|
184
|
+
"summary": "Strong product taste, per the user."
|
|
185
|
+
},
|
|
172
186
|
"origin": {
|
|
173
187
|
"kind": "user",
|
|
174
188
|
"originalUserUtterance": "I think the founder has strong product taste."
|
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,28 @@ this project adheres to [Semantic Versioning](https://semver.org).
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
+
## [2.2.0] - 2026-09-04
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
- Define `human_subjective_view.people` and `human_subjective_view.business`
|
|
13
|
+
as the only Information types for a Llama user's own judgment. CLI and MCP
|
|
14
|
+
reject them locally unless `value.speaker` is set and `value.rawText`
|
|
15
|
+
appears verbatim inside `origin.originalUserUtterance`; retired aliases
|
|
16
|
+
(`human_view`, `human_statement`, `human_opinion`, `human_judgment`,
|
|
17
|
+
`partner_view`) are refused with the replacement named. Core enforces the
|
|
18
|
+
same rule server-side.
|
|
19
|
+
|
|
20
|
+
## [2.1.3] - 2026-09-03
|
|
21
|
+
|
|
22
|
+
### Added
|
|
23
|
+
- Add `llama page-schema list|read|section` and the matching
|
|
24
|
+
`get_live_deal_page_schema` MCP tool so Agents progressively load only the
|
|
25
|
+
exact Live Deal Page field contracts needed for a write.
|
|
26
|
+
|
|
27
|
+
### Changed
|
|
28
|
+
- Make Agent bootstrap and briefing request the compact Live Deal Page schema
|
|
29
|
+
index instead of downloading and repeating the complete field contract.
|
|
30
|
+
|
|
9
31
|
## [2.1.2] - 2026-09-03
|
|
10
32
|
|
|
11
33
|
### Fixed
|
package/README.md
CHANGED
|
@@ -180,7 +180,9 @@ Its Deal surface is also exactly four tools:
|
|
|
180
180
|
Authentication, skill discovery, Wiki, admin audit, preferences, and external
|
|
181
181
|
pitch remain separate non-Deal domains. Deal Memory likewise has two separate
|
|
182
182
|
MCP tools, `get_deal_memory` and `update_deal_memory`; it does not add a fifth
|
|
183
|
-
Occam Deal tool.
|
|
183
|
+
Occam Deal tool. `get_live_deal_page_schema` progressively reads the Page
|
|
184
|
+
schema index, exact fields, or one section; it is read-only context rather than
|
|
185
|
+
a fifth Deal action.
|
|
184
186
|
|
|
185
187
|
## Agent bootstrap
|
|
186
188
|
|
|
@@ -192,10 +194,12 @@ llama skills show <slug>
|
|
|
192
194
|
|
|
193
195
|
Agents should run `llama agent bootstrap` before Deal work. The command loads
|
|
194
196
|
the authenticated, server-owned private Brain: Investment Framework V3 for
|
|
195
|
-
thinking plus the Llama Command operating skill for working. It also loads
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
197
|
+
thinking plus the Llama Command operating skill for working. It also loads a
|
|
198
|
+
compact index of the current Live Deal Page fields. Before `page.patch`, use
|
|
199
|
+
`llama page-schema read <field> [field...]` to load only the exact field
|
|
200
|
+
contracts being changed, or `llama page-schema section <section>` when the
|
|
201
|
+
write genuinely spans a section. None of that private content is shipped in
|
|
202
|
+
this public package; CLI is only the tool and authenticated transport.
|
|
199
203
|
|
|
200
204
|
The live server briefing is authoritative. The bundled
|
|
201
205
|
`AGENT_BRIEFING.md` is an offline fallback with the same four-action contract.
|
package/README.zh-CN.md
CHANGED
|
@@ -170,12 +170,15 @@ MCP 的 Deal 工具同样恰好四个:
|
|
|
170
170
|
认证、skill discovery、Wiki、admin audit、preferences 和 external pitch
|
|
171
171
|
属于其他独立领域,不会扩大 Deal action space。Deal Memory 同样是独立领域,
|
|
172
172
|
对应 `get_deal_memory` 和 `update_deal_memory` 两个 MCP 工具,并不增加第五个
|
|
173
|
-
Occam Deal
|
|
173
|
+
Occam Deal 工具。`get_live_deal_page_schema` 以渐进方式读取 Page schema 的
|
|
174
|
+
索引、精确字段或一个 section;它是只读上下文,也不是第五个 Deal action。
|
|
174
175
|
|
|
175
176
|
## Agent 启动
|
|
176
177
|
|
|
177
178
|
```bash
|
|
178
179
|
llama agent bootstrap
|
|
180
|
+
llama page-schema list
|
|
181
|
+
llama page-schema read <field> [field...]
|
|
179
182
|
llama skills search "<任务>"
|
|
180
183
|
llama skills show <slug>
|
|
181
184
|
```
|
|
@@ -183,8 +186,10 @@ llama skills show <slug>
|
|
|
183
186
|
Agent 在处理 Deal 前应先运行 `llama agent bootstrap`。该命令会从鉴权后的
|
|
184
187
|
Llama Command 服务端加载两部分私有 Brain:负责投资思考的 Investment
|
|
185
188
|
Framework V3,以及负责如何在 Command 工作的 Llama Command operating skill;
|
|
186
|
-
|
|
187
|
-
|
|
189
|
+
同时加载实时 Live Deal Page 字段的精简索引。执行 `page.patch` 前,通过
|
|
190
|
+
`llama page-schema read <field> [field...]` 只加载本次修改所需的字段契约;
|
|
191
|
+
只有当写入确实跨越一个 section 时才加载整个 section。所有私有内容都不会进入
|
|
192
|
+
公开 npm 包;CLI 只是 Agent 的工具和鉴权运输层。
|
|
188
193
|
|
|
189
194
|
服务端实时 briefing 是权威合同;包内 `AGENT_BRIEFING.md` 是相同四动作
|
|
190
195
|
合同的离线兜底。
|
package/bin/llama-mcp.mjs
CHANGED
|
@@ -26,6 +26,7 @@ import {
|
|
|
26
26
|
prepareDealCommand,
|
|
27
27
|
} from "../lib/deal-actions.mjs";
|
|
28
28
|
import { buildDealMemoryPath } from "../lib/deal-memory-actions.mjs";
|
|
29
|
+
import { buildPageSchemaPath, MAX_PAGE_SCHEMA_FIELDS } from "../lib/page-schema.mjs";
|
|
29
30
|
|
|
30
31
|
const requireFromHere = createRequire(import.meta.url);
|
|
31
32
|
const { version: PKG_VERSION } = requireFromHere("../package.json");
|
|
@@ -151,7 +152,7 @@ server.registerTool(
|
|
|
151
152
|
server.registerTool(
|
|
152
153
|
"write_deal",
|
|
153
154
|
{
|
|
154
|
-
description: "The only Deal mutation tool. Pass one command: input.submit, information.put, page.patch, or artifact.put. All Page content fields are Agent-writable; author controls attribution, not permission.
|
|
155
|
+
description: "The only Deal mutation tool. Pass one command: input.submit, information.put, page.patch, or artifact.put. All Page content fields are Agent-writable; author controls attribution, not permission. Before page.patch, use get_live_deal_page_schema for the exact fields being changed and write bilingual Page prose. page.patch is JSON Merge Patch: arrays replace whole arrays, so read-modify-write and preserve sibling slots. A Llama user's own judgment is human_subjective_view.people or human_subjective_view.business and must carry value.speaker plus value.rawText quoted verbatim from origin.originalUserUtterance; it is rejected otherwise.",
|
|
155
156
|
// MCP SDK 1.30 only publishes object schemas at the tool root. Nesting one
|
|
156
157
|
// command preserves the real discriminated union instead of flattening four
|
|
157
158
|
// incompatible operations into false affordances.
|
|
@@ -216,11 +217,12 @@ server.registerTool(
|
|
|
216
217
|
server.registerTool(
|
|
217
218
|
"agent_bootstrap",
|
|
218
219
|
{
|
|
219
|
-
description: "Mandatory before Llama work: fetch the authenticated two-part private Brain (Investment Framework V3 + Llama Command operating skill),
|
|
220
|
+
description: "Mandatory before Llama work: fetch the authenticated two-part private Brain (Investment Framework V3 + Llama Command operating skill), a compact Live Deal Page schema index, runtime contract, and visible Llama OS skills. Read exact Page fields separately with get_live_deal_page_schema.",
|
|
220
221
|
inputSchema: { limit: z.number().int().min(1).max(100).optional() },
|
|
221
222
|
},
|
|
222
223
|
async ({ limit } = {}) => {
|
|
223
224
|
const params = new URLSearchParams({ clientVersion: PKG_VERSION });
|
|
225
|
+
params.set("page_schema", "progressive");
|
|
224
226
|
if (limit) params.set("limit", String(limit));
|
|
225
227
|
try {
|
|
226
228
|
const result = await request("GET", `/api/agent/manifest?${params}`);
|
|
@@ -231,6 +233,25 @@ server.registerTool(
|
|
|
231
233
|
},
|
|
232
234
|
);
|
|
233
235
|
|
|
236
|
+
server.registerTool(
|
|
237
|
+
"get_live_deal_page_schema",
|
|
238
|
+
{
|
|
239
|
+
description: "Read the Live Deal Page schema progressively. Call with no selector for the compact index; before page.patch, request only exact fields or one section. This is read-only context, not a fifth Deal action.",
|
|
240
|
+
inputSchema: {
|
|
241
|
+
fields: z.array(z.string().min(1)).min(1).max(MAX_PAGE_SCHEMA_FIELDS).optional(),
|
|
242
|
+
section: z.string().min(1).optional(),
|
|
243
|
+
},
|
|
244
|
+
},
|
|
245
|
+
async ({ fields, section } = {}) => {
|
|
246
|
+
try {
|
|
247
|
+
// @core-api-operation GET /api/agent/page-schema
|
|
248
|
+
return await callApi("GET", buildPageSchemaPath({ fields, section }));
|
|
249
|
+
} catch (error) {
|
|
250
|
+
return textResult(formatErrorForDisplay(error), true);
|
|
251
|
+
}
|
|
252
|
+
},
|
|
253
|
+
);
|
|
254
|
+
|
|
234
255
|
server.registerTool(
|
|
235
256
|
"skills_search",
|
|
236
257
|
{
|
|
@@ -430,7 +451,7 @@ server.registerTool(
|
|
|
430
451
|
server.registerPrompt(
|
|
431
452
|
"agent_briefing",
|
|
432
453
|
{
|
|
433
|
-
description: "Mandatory before Llama work: fetch the authenticated two-part private Brain,
|
|
454
|
+
description: "Mandatory before Llama work: fetch the authenticated two-part private Brain, compact Live Deal Page schema index, and runtime contract; read exact fields separately with get_live_deal_page_schema. Bundled text is only an offline fallback.",
|
|
434
455
|
},
|
|
435
456
|
async () => {
|
|
436
457
|
const headers = await getAuthHeaders();
|
|
@@ -440,6 +461,7 @@ server.registerPrompt(
|
|
|
440
461
|
} else {
|
|
441
462
|
try {
|
|
442
463
|
const params = new URLSearchParams({ clientVersion: PKG_VERSION });
|
|
464
|
+
params.set("page_schema", "progressive");
|
|
443
465
|
const response = await request("GET", `/api/agent/briefing?${params}`);
|
|
444
466
|
text = response?.briefing || readBriefing();
|
|
445
467
|
} catch (error) {
|
package/bin/llama.mjs
CHANGED
|
@@ -43,6 +43,7 @@ import {
|
|
|
43
43
|
buildDealMemoryPath,
|
|
44
44
|
readMarkdownInput,
|
|
45
45
|
} from "../lib/deal-memory-actions.mjs";
|
|
46
|
+
import { buildPageSchemaPath } from "../lib/page-schema.mjs";
|
|
46
47
|
|
|
47
48
|
const requireFromHere = createRequire(import.meta.url);
|
|
48
49
|
const { version: PKG_VERSION } = requireFromHere("../package.json");
|
|
@@ -65,6 +66,7 @@ Separate preserved domains:
|
|
|
65
66
|
llama auth status|login|logout
|
|
66
67
|
llama token set|show
|
|
67
68
|
llama agent bootstrap
|
|
69
|
+
llama page-schema list|read|section
|
|
68
70
|
llama skills list|search|show
|
|
69
71
|
llama pref list|add|approve|retire
|
|
70
72
|
llama explain <url-or-object>
|
|
@@ -84,14 +86,16 @@ Exactly four actions:
|
|
|
84
86
|
|
|
85
87
|
Before any Page write:
|
|
86
88
|
llama agent bootstrap
|
|
89
|
+
llama page-schema read <field> [field...]
|
|
87
90
|
|
|
88
91
|
The authenticated bootstrap contains the two-part private Llama Brain:
|
|
89
92
|
Investment Framework V3 plus the Llama Command operating skill. It also
|
|
90
|
-
contains
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
93
|
+
contains a compact index of the current Page fields. Before page.patch, use
|
|
94
|
+
the separate page-schema command to read only the exact fields being changed,
|
|
95
|
+
or one section when necessary. CLI is the tool, not Brain. Information never
|
|
96
|
+
updates Page automatically. page.patch is JSON Merge Patch: objects merge,
|
|
97
|
+
null deletes, and arrays replace whole arrays, so read-modify-write complete
|
|
98
|
+
Page arrays and preserve sibling slots.
|
|
95
99
|
|
|
96
100
|
create JSON:
|
|
97
101
|
{"companyName":"Acme","page":{},"information":[],"origin":{"kind":"user","originalUserUtterance":"..."}}
|
|
@@ -99,6 +103,7 @@ create JSON:
|
|
|
99
103
|
write JSON (CLI derives idempotencyKey when omitted):
|
|
100
104
|
input.submit: {"operation":"input.submit","dealId":"<uuid>","content":"<original input>","format":"text","source":{},"origin":{"kind":"user","originalUserUtterance":"..."}}
|
|
101
105
|
information.put:{"operation":"information.put","dealId":"<uuid>","type":"founder_claim","labels":["founder-stated"],"subject":{"topic":"traction"},"value":{"content":"...","source":{"kind":"first_meeting_transcript"}},"origin":{"kind":"user","originalUserUtterance":"..."}}
|
|
106
|
+
human judgment: {"operation":"information.put","dealId":"<uuid>","type":"human_subjective_view.people","subject":{"topic":"founder_execution"},"value":{"speaker":"<Llama user>","rawText":"<the user's verbatim words>","summary":"<optional agent summary>"},"origin":{"kind":"user","originalUserUtterance":"<complete user input; must contain rawText>"}}
|
|
102
107
|
page.patch: {"operation":"page.patch","dealId":"<uuid>","patch":{"description":{"en":"...","zh":"..."}},"origin":{"kind":"agent"}}
|
|
103
108
|
artifact.put: {"operation":"artifact.put","dealId":"<uuid>","kind":"deck","title":"deck.pdf","mimeType":"application/pdf","contentBase64":"<file bytes, base64>","origin":{"kind":"user","originalUserUtterance":"..."}}
|
|
104
109
|
|
|
@@ -111,6 +116,12 @@ with storageKey (+ optional storageUrl) plus byteSize and sha256 instead.
|
|
|
111
116
|
For Information, origin records who caused the write and preserves user words;
|
|
112
117
|
value.source records where the evidence came from.
|
|
113
118
|
|
|
119
|
+
human_subjective_view.people|business is a Llama user's own judgment about the
|
|
120
|
+
team or the deal. Subjective = the truth depends on who judges: a value or
|
|
121
|
+
comparative word with no benchmark, or a claim about someone's future behavior
|
|
122
|
+
or inner state. It requires value.speaker and value.rawText quoted verbatim from
|
|
123
|
+
origin.originalUserUtterance; CLI and Core reject anything else. Other types are free.
|
|
124
|
+
|
|
114
125
|
Core owns Chat Records, append-only Deal Events, Drive provisioning, audit,
|
|
115
126
|
and idempotency. User-originated work must preserve exact wording in
|
|
116
127
|
origin.originalUserUtterance or reference origin.originatingChatRecordId.`;
|
|
@@ -142,6 +153,16 @@ read this Story.
|
|
|
142
153
|
This uses your existing Llama authentication. The CLI talks only to Command
|
|
143
154
|
Core and never receives Deal Memory service credentials or AWS access.`;
|
|
144
155
|
|
|
156
|
+
const HELP_PAGE_SCHEMA = `Llama Live Deal Page schema — progressive, read-only context
|
|
157
|
+
|
|
158
|
+
llama page-schema list
|
|
159
|
+
llama page-schema read <field> [field...]
|
|
160
|
+
llama page-schema section <section>
|
|
161
|
+
|
|
162
|
+
Start with list. Before page.patch, read only the exact fields being changed;
|
|
163
|
+
use a section read only when the write genuinely spans that section. This is a
|
|
164
|
+
schema/field-prompt surface, not a fifth Deal action and not Page data.`;
|
|
165
|
+
|
|
145
166
|
function parseFlags(args, allowed = null) {
|
|
146
167
|
const flags = {};
|
|
147
168
|
const positional = [];
|
|
@@ -168,7 +189,12 @@ function parseFlags(args, allowed = null) {
|
|
|
168
189
|
}
|
|
169
190
|
|
|
170
191
|
function usage(area) {
|
|
171
|
-
console.log(
|
|
192
|
+
console.log(
|
|
193
|
+
area === "deal" ? HELP_DEAL :
|
|
194
|
+
area === "memory" ? HELP_MEMORY :
|
|
195
|
+
area === "page-schema" ? HELP_PAGE_SCHEMA :
|
|
196
|
+
HELP_ROOT,
|
|
197
|
+
);
|
|
172
198
|
}
|
|
173
199
|
|
|
174
200
|
function assertDealAction(area, action) {
|
|
@@ -502,6 +528,7 @@ async function main() {
|
|
|
502
528
|
}
|
|
503
529
|
try {
|
|
504
530
|
const params = new URLSearchParams({ clientVersion: PKG_VERSION });
|
|
531
|
+
params.set("page_schema", "progressive");
|
|
505
532
|
const response = await request("GET", `/api/agent/briefing?${params}`);
|
|
506
533
|
process.stdout.write(response?.briefing || readBriefing());
|
|
507
534
|
} catch (error) {
|
|
@@ -514,6 +541,7 @@ async function main() {
|
|
|
514
541
|
if (area === "agent" && action === "bootstrap") {
|
|
515
542
|
const { flags } = parseFlags(rest, ["json", "limit"]);
|
|
516
543
|
const params = new URLSearchParams({ clientVersion: PKG_VERSION });
|
|
544
|
+
params.set("page_schema", "progressive");
|
|
517
545
|
if (flags.limit && flags.limit !== true) params.set("limit", String(flags.limit));
|
|
518
546
|
const manifest = await request("GET", `/api/agent/manifest?${params}`);
|
|
519
547
|
if (flags.json) print(structuredBootstrapManifest(manifest));
|
|
@@ -521,6 +549,28 @@ async function main() {
|
|
|
521
549
|
return;
|
|
522
550
|
}
|
|
523
551
|
|
|
552
|
+
if (area === "page-schema") {
|
|
553
|
+
if (!action || action === "list") {
|
|
554
|
+
if (rest.length) throw new Error("Usage: llama page-schema list");
|
|
555
|
+
// @core-api-operation GET /api/agent/page-schema
|
|
556
|
+
print(await request("GET", buildPageSchemaPath()));
|
|
557
|
+
return;
|
|
558
|
+
}
|
|
559
|
+
if (action === "read") {
|
|
560
|
+
if (!rest.length) throw new Error("Usage: llama page-schema read <field> [field...]");
|
|
561
|
+
// @core-api-operation GET /api/agent/page-schema
|
|
562
|
+
print(await request("GET", buildPageSchemaPath({ fields: rest })));
|
|
563
|
+
return;
|
|
564
|
+
}
|
|
565
|
+
if (action === "section") {
|
|
566
|
+
if (rest.length !== 1) throw new Error("Usage: llama page-schema section <section>");
|
|
567
|
+
// @core-api-operation GET /api/agent/page-schema
|
|
568
|
+
print(await request("GET", buildPageSchemaPath({ section: rest[0] })));
|
|
569
|
+
return;
|
|
570
|
+
}
|
|
571
|
+
throw new Error("Page schema actions: list, read, section.");
|
|
572
|
+
}
|
|
573
|
+
|
|
524
574
|
if (area === "skills" || (area === "agent" && action === "skills")) {
|
|
525
575
|
const sub = area === "skills" ? action : rest[0];
|
|
526
576
|
const args = area === "skills" ? rest : rest.slice(1);
|
package/contracts/core-api.json
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"format": "llama.core-api-contract.v1",
|
|
3
3
|
"name": "llama-core-api",
|
|
4
|
-
"apiVersion": "5.
|
|
4
|
+
"apiVersion": "5.3.0",
|
|
5
5
|
"openapiVersion": "3.0.3",
|
|
6
|
-
"sha256": "
|
|
7
|
-
"pathCount":
|
|
8
|
-
"operationCount":
|
|
6
|
+
"sha256": "b793f67038b48cdfbfcc9141153132689c40e84adfbe087b0dbef3a409f5e5d5",
|
|
7
|
+
"pathCount": 113,
|
|
8
|
+
"operationCount": 140
|
|
9
9
|
}
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
{ "method": "GET", "path": "/api/agent/briefing" },
|
|
10
10
|
{ "method": "GET", "path": "/api/agent/explain" },
|
|
11
11
|
{ "method": "GET", "path": "/api/agent/manifest" },
|
|
12
|
+
{ "method": "GET", "path": "/api/agent/page-schema" },
|
|
12
13
|
{ "method": "GET", "path": "/api/agent/preferences" },
|
|
13
14
|
{ "method": "GET", "path": "/api/agent/skills" },
|
|
14
15
|
{ "method": "GET", "path": "/api/agent/skills/{slug}" },
|
package/lib/build-manifest.json
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"format": "llama.cli-build.v1",
|
|
3
3
|
"packageName": "@llamaventures/cli",
|
|
4
|
-
"packageVersion": "2.
|
|
5
|
-
"sourceSha": "
|
|
4
|
+
"packageVersion": "2.2.0",
|
|
5
|
+
"sourceSha": "2f4c73310ed6c5d36a47a275490ff1082321ca27",
|
|
6
6
|
"sourceKind": "github",
|
|
7
7
|
"sourceDirty": false,
|
|
8
8
|
"coreApiContract": {
|
|
9
9
|
"format": "llama.core-api-contract.v1",
|
|
10
10
|
"name": "llama-core-api",
|
|
11
|
-
"apiVersion": "5.
|
|
11
|
+
"apiVersion": "5.3.0",
|
|
12
12
|
"openapiVersion": "3.0.3",
|
|
13
|
-
"sha256": "
|
|
13
|
+
"sha256": "b793f67038b48cdfbfcc9141153132689c40e84adfbe087b0dbef3a409f5e5d5"
|
|
14
14
|
}
|
|
15
15
|
}
|
package/lib/deal-actions.mjs
CHANGED
|
@@ -9,6 +9,72 @@ export const DEAL_WRITE_OPERATIONS = Object.freeze([
|
|
|
9
9
|
"artifact.put",
|
|
10
10
|
]);
|
|
11
11
|
|
|
12
|
+
/**
|
|
13
|
+
* A Llama user's own subjective judgment about the team (.people) or the deal
|
|
14
|
+
* (.business). An agent may record it, but the record must name the user and
|
|
15
|
+
* quote them verbatim from their own input, so the type alone stays a reliable
|
|
16
|
+
* filter. Core enforces the same rule; this check only fails faster.
|
|
17
|
+
*/
|
|
18
|
+
export const HUMAN_SUBJECTIVE_VIEW_TYPES = Object.freeze([
|
|
19
|
+
"human_subjective_view.people",
|
|
20
|
+
"human_subjective_view.business",
|
|
21
|
+
]);
|
|
22
|
+
|
|
23
|
+
const RETIRED_HUMAN_VIEW_TYPES = Object.freeze([
|
|
24
|
+
"human_view",
|
|
25
|
+
"human_statement",
|
|
26
|
+
"human_opinion",
|
|
27
|
+
"human_judgment",
|
|
28
|
+
"partner_view",
|
|
29
|
+
]);
|
|
30
|
+
|
|
31
|
+
function normalizeWhitespace(text) {
|
|
32
|
+
return String(text).replace(/\s+/g, " ").trim();
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function stringField(object, key) {
|
|
36
|
+
const value = object && typeof object === "object" && !Array.isArray(object) ? object[key] : undefined;
|
|
37
|
+
return typeof value === "string" ? value.trim() : "";
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export function validateHumanSubjectiveView(information, origin) {
|
|
41
|
+
const type = stringField(information, "type");
|
|
42
|
+
const lower = type.toLowerCase();
|
|
43
|
+
if (RETIRED_HUMAN_VIEW_TYPES.includes(lower) || lower.startsWith("human_view.")) {
|
|
44
|
+
throw new Error(
|
|
45
|
+
`Information type "${type}" is retired: a Llama user's own judgment is human_subjective_view.people or human_subjective_view.business`,
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
if (lower !== "human_subjective_view" && !lower.startsWith("human_subjective_view.")) {
|
|
49
|
+
return information;
|
|
50
|
+
}
|
|
51
|
+
if (!HUMAN_SUBJECTIVE_VIEW_TYPES.includes(type)) {
|
|
52
|
+
throw new Error(
|
|
53
|
+
"human_subjective_view must be exactly human_subjective_view.people (team) or human_subjective_view.business (deal)",
|
|
54
|
+
);
|
|
55
|
+
}
|
|
56
|
+
const utterance = origin?.kind === "user" ? stringField(origin, "originalUserUtterance") : "";
|
|
57
|
+
if (!utterance) {
|
|
58
|
+
throw new Error(
|
|
59
|
+
"human_subjective_view.* must originate from a user and carry the user's words in origin.originalUserUtterance",
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
const speaker = stringField(information.value, "speaker");
|
|
63
|
+
const rawText = stringField(information.value, "rawText");
|
|
64
|
+
if (!speaker) {
|
|
65
|
+
throw new Error("human_subjective_view.* requires value.speaker: the Llama user whose judgment this is");
|
|
66
|
+
}
|
|
67
|
+
if (!rawText) {
|
|
68
|
+
throw new Error("human_subjective_view.* requires value.rawText: the user's verbatim words");
|
|
69
|
+
}
|
|
70
|
+
if (!normalizeWhitespace(utterance).includes(normalizeWhitespace(rawText))) {
|
|
71
|
+
throw new Error(
|
|
72
|
+
"human_subjective_view.* value.rawText must appear verbatim inside origin.originalUserUtterance; do not paraphrase",
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
return information;
|
|
76
|
+
}
|
|
77
|
+
|
|
12
78
|
function canonicalJson(value) {
|
|
13
79
|
if (Array.isArray(value)) return `[${value.map(canonicalJson).join(",")}]`;
|
|
14
80
|
if (value && typeof value === "object") {
|
|
@@ -153,9 +219,14 @@ export function prepareDealCommand(action, input) {
|
|
|
153
219
|
}
|
|
154
220
|
if (action === "create") {
|
|
155
221
|
validateLocalizedTextPairs(command.page ?? {});
|
|
222
|
+
const information = Array.isArray(command.information) ? command.information : [];
|
|
223
|
+
for (const item of information) validateHumanSubjectiveView(item, command.origin);
|
|
156
224
|
}
|
|
157
225
|
if (action === "write" && command.operation === "page.patch") {
|
|
158
226
|
validateLocalizedTextPairs(command.patch ?? {});
|
|
159
227
|
}
|
|
228
|
+
if (action === "write" && command.operation === "information.put") {
|
|
229
|
+
validateHumanSubjectiveView(command, command.origin);
|
|
230
|
+
}
|
|
160
231
|
return ensureIdempotencyKey(validateCommandOrigin(command));
|
|
161
232
|
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export const LIVE_DEAL_PAGE_SCHEMA_PATH = "/api/agent/page-schema";
|
|
2
|
+
export const MAX_PAGE_SCHEMA_FIELDS = 20;
|
|
3
|
+
|
|
4
|
+
export function buildPageSchemaPath({ fields = [], section } = {}) {
|
|
5
|
+
const normalizedFields = [...new Set(
|
|
6
|
+
fields.map((field) => String(field).trim()).filter(Boolean),
|
|
7
|
+
)];
|
|
8
|
+
const normalizedSection = section === undefined ? "" : String(section).trim();
|
|
9
|
+
|
|
10
|
+
if (normalizedFields.length && normalizedSection) {
|
|
11
|
+
throw new Error("Choose exact fields or one section, not both.");
|
|
12
|
+
}
|
|
13
|
+
if (normalizedFields.length > MAX_PAGE_SCHEMA_FIELDS) {
|
|
14
|
+
throw new Error(`Choose at most ${MAX_PAGE_SCHEMA_FIELDS} exact fields per request.`);
|
|
15
|
+
}
|
|
16
|
+
if (section !== undefined && !normalizedSection) {
|
|
17
|
+
throw new Error("Page schema section cannot be empty.");
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const params = new URLSearchParams();
|
|
21
|
+
for (const field of normalizedFields) params.append("field", field);
|
|
22
|
+
if (normalizedSection) params.set("section", normalizedSection);
|
|
23
|
+
return `${LIVE_DEAL_PAGE_SCHEMA_PATH}${params.size ? `?${params}` : ""}`;
|
|
24
|
+
}
|
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@llamaventures/cli",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.2.0",
|
|
4
4
|
"description": "CLI + MCP server for the Llama Ventures investment workbench (command.llamaventures.vc).",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"scripts": {
|
|
7
7
|
"test": "npm run test:agent-routing && npm run test:contract",
|
|
8
8
|
"test:agent-routing": "node scripts/verify-agent-routing.mjs",
|
|
9
|
-
"test:contract": "node --test scripts/build-manifest.test.mjs scripts/core-api-call-sites.test.mjs scripts/deal-actions-cli.test.mjs scripts/deal-actions.test.mjs scripts/deal-memory-actions-cli.test.mjs scripts/deal-memory-actions.test.mjs scripts/mcp-four-action-surface.test.mjs scripts/server-compatibility.test.mjs scripts/verify-core-api-contract.test.mjs && node scripts/verify-core-api-contract.mjs",
|
|
9
|
+
"test:contract": "node --test scripts/build-manifest.test.mjs scripts/core-api-call-sites.test.mjs scripts/deal-actions-cli.test.mjs scripts/deal-actions.test.mjs scripts/deal-memory-actions-cli.test.mjs scripts/deal-memory-actions.test.mjs scripts/mcp-four-action-surface.test.mjs scripts/page-schema-cli.test.mjs scripts/page-schema.test.mjs scripts/server-compatibility.test.mjs scripts/verify-core-api-contract.test.mjs && node scripts/verify-core-api-contract.mjs",
|
|
10
10
|
"verify:artifact": "node scripts/verify-release-artifact.mjs",
|
|
11
11
|
"verify:release": "npm test && npm run verify:artifact && node scripts/verify-tarball-clean.mjs",
|
|
12
12
|
"prepack": "node scripts/prepare-build-manifest.mjs",
|