@llamaventures/cli 2.1.3 → 2.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/AGENT_BRIEFING.md +17 -4
- package/CHANGELOG.md +19 -0
- package/bin/llama-mcp.mjs +1 -1
- package/bin/llama.mjs +8 -0
- package/lib/build-manifest.json +2 -2
- package/lib/deal-actions.mjs +79 -0
- package/package.json +1 -1
package/AGENT_BRIEFING.md
CHANGED
|
@@ -162,16 +162,29 @@ Always submit raw user information first when losing it would be unacceptable:
|
|
|
162
162
|
}
|
|
163
163
|
```
|
|
164
164
|
|
|
165
|
-
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, `value.rawText` quotes the user verbatim
|
|
172
|
+
from `origin.originalUserUtterance`, and `value.summary` is your own
|
|
173
|
+
restatement of those words (never a substitute for them). CLI and Core reject
|
|
174
|
+
anything else. If no, choose any type that fits; founder words are
|
|
175
|
+
`founder_claim`.
|
|
166
176
|
|
|
167
177
|
```json
|
|
168
178
|
{
|
|
169
179
|
"operation": "information.put",
|
|
170
180
|
"dealId": "<uuid>",
|
|
171
|
-
"type": "
|
|
172
|
-
"labels": ["human_view"],
|
|
181
|
+
"type": "human_subjective_view.people",
|
|
173
182
|
"subject": {"person": "Founder name"},
|
|
174
|
-
"value": {
|
|
183
|
+
"value": {
|
|
184
|
+
"speaker": "<Llama user>",
|
|
185
|
+
"rawText": "I think the founder has strong product taste.",
|
|
186
|
+
"summary": "Strong product taste, per the user."
|
|
187
|
+
},
|
|
175
188
|
"origin": {
|
|
176
189
|
"kind": "user",
|
|
177
190
|
"originalUserUtterance": "I think the founder has strong product taste."
|
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,25 @@ this project adheres to [Semantic Versioning](https://semver.org).
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
+
## [2.3.0] - 2026-09-04
|
|
10
|
+
|
|
11
|
+
### Changed
|
|
12
|
+
- `human_subjective_view.people|business` now also requires `value.summary`,
|
|
13
|
+
the agent's own restatement of the user's words, and rejects a summary that
|
|
14
|
+
merely repeats `value.rawText`. Core enforces the same rule; the Deal Page
|
|
15
|
+
shows both the summary and the verbatim text.
|
|
16
|
+
|
|
17
|
+
## [2.2.0] - 2026-09-04
|
|
18
|
+
|
|
19
|
+
### Added
|
|
20
|
+
- Define `human_subjective_view.people` and `human_subjective_view.business`
|
|
21
|
+
as the only Information types for a Llama user's own judgment. CLI and MCP
|
|
22
|
+
reject them locally unless `value.speaker` is set and `value.rawText`
|
|
23
|
+
appears verbatim inside `origin.originalUserUtterance`; retired aliases
|
|
24
|
+
(`human_view`, `human_statement`, `human_opinion`, `human_judgment`,
|
|
25
|
+
`partner_view`) are refused with the replacement named. Core enforces the
|
|
26
|
+
same rule server-side.
|
|
27
|
+
|
|
9
28
|
## [2.1.3] - 2026-09-03
|
|
10
29
|
|
|
11
30
|
### Added
|
package/bin/llama-mcp.mjs
CHANGED
|
@@ -152,7 +152,7 @@ server.registerTool(
|
|
|
152
152
|
server.registerTool(
|
|
153
153
|
"write_deal",
|
|
154
154
|
{
|
|
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.",
|
|
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, value.rawText quoted verbatim from origin.originalUserUtterance, and value.summary (the agent's restatement); it is rejected otherwise.",
|
|
156
156
|
// MCP SDK 1.30 only publishes object schemas at the tool root. Nesting one
|
|
157
157
|
// command preserves the real discriminated union instead of flattening four
|
|
158
158
|
// incompatible operations into false affordances.
|
package/bin/llama.mjs
CHANGED
|
@@ -103,6 +103,7 @@ create JSON:
|
|
|
103
103
|
write JSON (CLI derives idempotencyKey when omitted):
|
|
104
104
|
input.submit: {"operation":"input.submit","dealId":"<uuid>","content":"<original input>","format":"text","source":{},"origin":{"kind":"user","originalUserUtterance":"..."}}
|
|
105
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":"<the agent's restatement>"},"origin":{"kind":"user","originalUserUtterance":"<complete user input; must contain rawText>"}}
|
|
106
107
|
page.patch: {"operation":"page.patch","dealId":"<uuid>","patch":{"description":{"en":"...","zh":"..."}},"origin":{"kind":"agent"}}
|
|
107
108
|
artifact.put: {"operation":"artifact.put","dealId":"<uuid>","kind":"deck","title":"deck.pdf","mimeType":"application/pdf","contentBase64":"<file bytes, base64>","origin":{"kind":"user","originalUserUtterance":"..."}}
|
|
108
109
|
|
|
@@ -115,6 +116,13 @@ with storageKey (+ optional storageUrl) plus byteSize and sha256 instead.
|
|
|
115
116
|
For Information, origin records who caused the write and preserves user words;
|
|
116
117
|
value.source records where the evidence came from.
|
|
117
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, value.rawText quoted verbatim from
|
|
123
|
+
origin.originalUserUtterance, and value.summary, the agent's own restatement of
|
|
124
|
+
those words; CLI and Core reject anything else. Other types are free.
|
|
125
|
+
|
|
118
126
|
Core owns Chat Records, append-only Deal Events, Drive provisioning, audit,
|
|
119
127
|
and idempotency. User-originated work must preserve exact wording in
|
|
120
128
|
origin.originalUserUtterance or reference origin.originatingChatRecordId.`;
|
package/lib/build-manifest.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"format": "llama.cli-build.v1",
|
|
3
3
|
"packageName": "@llamaventures/cli",
|
|
4
|
-
"packageVersion": "2.
|
|
5
|
-
"sourceSha": "
|
|
4
|
+
"packageVersion": "2.3.0",
|
|
5
|
+
"sourceSha": "c68a1849a4c43edbcc340a8f47f21cf16ca615ef",
|
|
6
6
|
"sourceKind": "github",
|
|
7
7
|
"sourceDirty": false,
|
|
8
8
|
"coreApiContract": {
|
package/lib/deal-actions.mjs
CHANGED
|
@@ -9,6 +9,80 @@ 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, plus the agent's own restatement in
|
|
16
|
+
* value.summary, so the type alone stays a reliable filter and every record
|
|
17
|
+
* reads the same way. Core enforces the same rule; this check only fails faster.
|
|
18
|
+
*/
|
|
19
|
+
export const HUMAN_SUBJECTIVE_VIEW_TYPES = Object.freeze([
|
|
20
|
+
"human_subjective_view.people",
|
|
21
|
+
"human_subjective_view.business",
|
|
22
|
+
]);
|
|
23
|
+
|
|
24
|
+
const RETIRED_HUMAN_VIEW_TYPES = Object.freeze([
|
|
25
|
+
"human_view",
|
|
26
|
+
"human_statement",
|
|
27
|
+
"human_opinion",
|
|
28
|
+
"human_judgment",
|
|
29
|
+
"partner_view",
|
|
30
|
+
]);
|
|
31
|
+
|
|
32
|
+
function normalizeWhitespace(text) {
|
|
33
|
+
return String(text).replace(/\s+/g, " ").trim();
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function stringField(object, key) {
|
|
37
|
+
const value = object && typeof object === "object" && !Array.isArray(object) ? object[key] : undefined;
|
|
38
|
+
return typeof value === "string" ? value.trim() : "";
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export function validateHumanSubjectiveView(information, origin) {
|
|
42
|
+
const type = stringField(information, "type");
|
|
43
|
+
const lower = type.toLowerCase();
|
|
44
|
+
if (RETIRED_HUMAN_VIEW_TYPES.includes(lower) || lower.startsWith("human_view.")) {
|
|
45
|
+
throw new Error(
|
|
46
|
+
`Information type "${type}" is retired: a Llama user's own judgment is human_subjective_view.people or human_subjective_view.business`,
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
if (lower !== "human_subjective_view" && !lower.startsWith("human_subjective_view.")) {
|
|
50
|
+
return information;
|
|
51
|
+
}
|
|
52
|
+
if (!HUMAN_SUBJECTIVE_VIEW_TYPES.includes(type)) {
|
|
53
|
+
throw new Error(
|
|
54
|
+
"human_subjective_view must be exactly human_subjective_view.people (team) or human_subjective_view.business (deal)",
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
const utterance = origin?.kind === "user" ? stringField(origin, "originalUserUtterance") : "";
|
|
58
|
+
if (!utterance) {
|
|
59
|
+
throw new Error(
|
|
60
|
+
"human_subjective_view.* must originate from a user and carry the user's words in origin.originalUserUtterance",
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
const speaker = stringField(information.value, "speaker");
|
|
64
|
+
const rawText = stringField(information.value, "rawText");
|
|
65
|
+
if (!speaker) {
|
|
66
|
+
throw new Error("human_subjective_view.* requires value.speaker: the Llama user whose judgment this is");
|
|
67
|
+
}
|
|
68
|
+
if (!rawText) {
|
|
69
|
+
throw new Error("human_subjective_view.* requires value.rawText: the user's verbatim words");
|
|
70
|
+
}
|
|
71
|
+
if (!normalizeWhitespace(utterance).includes(normalizeWhitespace(rawText))) {
|
|
72
|
+
throw new Error(
|
|
73
|
+
"human_subjective_view.* value.rawText must appear verbatim inside origin.originalUserUtterance; do not paraphrase",
|
|
74
|
+
);
|
|
75
|
+
}
|
|
76
|
+
const summary = stringField(information.value, "summary");
|
|
77
|
+
if (!summary) {
|
|
78
|
+
throw new Error("human_subjective_view.* requires value.summary: the agent's restatement of the user's words");
|
|
79
|
+
}
|
|
80
|
+
if (normalizeWhitespace(summary) === normalizeWhitespace(rawText)) {
|
|
81
|
+
throw new Error("human_subjective_view.* value.summary must restate value.rawText, not repeat it");
|
|
82
|
+
}
|
|
83
|
+
return information;
|
|
84
|
+
}
|
|
85
|
+
|
|
12
86
|
function canonicalJson(value) {
|
|
13
87
|
if (Array.isArray(value)) return `[${value.map(canonicalJson).join(",")}]`;
|
|
14
88
|
if (value && typeof value === "object") {
|
|
@@ -153,9 +227,14 @@ export function prepareDealCommand(action, input) {
|
|
|
153
227
|
}
|
|
154
228
|
if (action === "create") {
|
|
155
229
|
validateLocalizedTextPairs(command.page ?? {});
|
|
230
|
+
const information = Array.isArray(command.information) ? command.information : [];
|
|
231
|
+
for (const item of information) validateHumanSubjectiveView(item, command.origin);
|
|
156
232
|
}
|
|
157
233
|
if (action === "write" && command.operation === "page.patch") {
|
|
158
234
|
validateLocalizedTextPairs(command.patch ?? {});
|
|
159
235
|
}
|
|
236
|
+
if (action === "write" && command.operation === "information.put") {
|
|
237
|
+
validateHumanSubjectiveView(command, command.origin);
|
|
238
|
+
}
|
|
160
239
|
return ensureIdempotencyKey(validateCommandOrigin(command));
|
|
161
240
|
}
|