@abelxiaoxing/cadence 2.0.18 → 2.0.20
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 +1 -1
- package/src/conversation-context.mjs +22 -9
- package/src/native-build.ts +1 -1
- package/src/service/contracts/workbench.ts +16 -1
- package/src/service-host.mjs +41 -18
- package/web/dist/assets/cadence.css +1 -1
- package/web/dist/assets/cadence.js +10 -9
- package/web/dist/manifest.json +7 -7
package/package.json
CHANGED
|
@@ -21,6 +21,26 @@ function argumentsData(value, secrets) {
|
|
|
21
21
|
if (sanitizer.limited) throw new Error("Unsupported context arguments");
|
|
22
22
|
return parseWireJson(source, 64 * 1024);
|
|
23
23
|
}
|
|
24
|
+
function own(value, key) {
|
|
25
|
+
const d =
|
|
26
|
+
value && typeof value === "object"
|
|
27
|
+
? Object.getOwnPropertyDescriptor(value, key)
|
|
28
|
+
: undefined;
|
|
29
|
+
if (!d || !("value" in d)) throw new Error("Invalid usage");
|
|
30
|
+
return d.value;
|
|
31
|
+
}
|
|
32
|
+
// Pi adds optional usage breakdowns per provider and release (reasoning, cacheWrite1h);
|
|
33
|
+
// retain only the counts every assistant message carries, read as own data properties.
|
|
34
|
+
function counts(value, keys) {
|
|
35
|
+
const out = Object.create(null);
|
|
36
|
+
for (const key of keys) {
|
|
37
|
+
const n = own(value, key);
|
|
38
|
+
if (typeof n !== "number" || !Number.isFinite(n) || n < 0)
|
|
39
|
+
throw new Error("Invalid usage");
|
|
40
|
+
out[key] = n;
|
|
41
|
+
}
|
|
42
|
+
return out;
|
|
43
|
+
}
|
|
24
44
|
/** Deliberately retain text and tool exchanges, not just last assistant prose. */
|
|
25
45
|
export function conversationMessages(messages, secrets = []) {
|
|
26
46
|
return list(messages, 4096, (message) => {
|
|
@@ -54,27 +74,20 @@ export function conversationMessages(messages, secrets = []) {
|
|
|
54
74
|
toolName: clean(message.toolName, secrets, 128),
|
|
55
75
|
isError: message.isError === true,
|
|
56
76
|
};
|
|
57
|
-
const usage =
|
|
77
|
+
const usage = counts(message.usage, [
|
|
58
78
|
"input",
|
|
59
79
|
"output",
|
|
60
80
|
"cacheRead",
|
|
61
81
|
"cacheWrite",
|
|
62
82
|
"totalTokens",
|
|
63
|
-
"cost",
|
|
64
83
|
]);
|
|
65
|
-
|
|
84
|
+
usage.cost = counts(own(message.usage, "cost"), [
|
|
66
85
|
"input",
|
|
67
86
|
"output",
|
|
68
87
|
"cacheRead",
|
|
69
88
|
"cacheWrite",
|
|
70
89
|
"total",
|
|
71
90
|
]);
|
|
72
|
-
for (const value of [
|
|
73
|
-
...Object.values(usage).filter((v) => typeof v !== "object"),
|
|
74
|
-
...Object.values(cost),
|
|
75
|
-
])
|
|
76
|
-
if (typeof value !== "number" || !Number.isFinite(value) || value < 0)
|
|
77
|
-
throw new Error("Invalid usage");
|
|
78
91
|
return {
|
|
79
92
|
role,
|
|
80
93
|
timestamp,
|
package/src/native-build.ts
CHANGED
|
@@ -66,6 +66,9 @@ export interface ChatTurn {
|
|
|
66
66
|
status: ChatStatus;
|
|
67
67
|
items: ChatItem[];
|
|
68
68
|
notice: string;
|
|
69
|
+
/** Content kinds observed and not retained; never written into `notice`.
|
|
70
|
+
* `other` is a block of a type Cadence does not recognize. */
|
|
71
|
+
omitted: { thinking: boolean; media: boolean; other: boolean };
|
|
69
72
|
}
|
|
70
73
|
export interface ChatSummary {
|
|
71
74
|
id: string;
|
|
@@ -199,12 +202,24 @@ export function decodeWorkbenchCommand(v: unknown): WorkbenchCommand {
|
|
|
199
202
|
};
|
|
200
203
|
}
|
|
201
204
|
export function decodeChatTurn(v: unknown): ChatTurn {
|
|
202
|
-
|
|
205
|
+
// Turns saved before `omitted` existed lack it; their flags read as unobserved.
|
|
206
|
+
const keys = ["id", "epoch", "status", "items", "notice"];
|
|
207
|
+
const current =
|
|
208
|
+
v !== null && typeof v === "object" && Object.hasOwn(v, "omitted");
|
|
209
|
+
const o = closed(v, current ? [...keys, "omitted"] : keys);
|
|
210
|
+
const omitted = current
|
|
211
|
+
? closed(o.omitted, ["thinking", "media", "other"])
|
|
212
|
+
: null;
|
|
203
213
|
return {
|
|
204
214
|
id: decodeId(o.id),
|
|
205
215
|
epoch: decodeId(o.epoch),
|
|
206
216
|
status: oneOf(o.status, statuses),
|
|
207
217
|
notice: text(o.notice, 1024),
|
|
218
|
+
omitted: {
|
|
219
|
+
thinking: omitted ? bool(omitted.thinking) : false,
|
|
220
|
+
media: omitted ? bool(omitted.media) : false,
|
|
221
|
+
other: omitted ? bool(omitted.other) : false,
|
|
222
|
+
},
|
|
208
223
|
items: list(o.items, 256, (v) => {
|
|
209
224
|
const i = closed(v, ["id", "role", "text", "name", "args", "error"]);
|
|
210
225
|
return {
|
package/src/service-host.mjs
CHANGED
|
@@ -4006,12 +4006,20 @@ function decodeWorkbenchCommand(v) {
|
|
|
4006
4006
|
};
|
|
4007
4007
|
}
|
|
4008
4008
|
function decodeChatTurn(v) {
|
|
4009
|
-
const
|
|
4009
|
+
const keys2 = ["id", "epoch", "status", "items", "notice"];
|
|
4010
|
+
const current = v !== null && typeof v === "object" && Object.hasOwn(v, "omitted");
|
|
4011
|
+
const o = closed(v, current ? [...keys2, "omitted"] : keys2);
|
|
4012
|
+
const omitted = current ? closed(o.omitted, ["thinking", "media", "other"]) : null;
|
|
4010
4013
|
return {
|
|
4011
4014
|
id: decodeId(o.id),
|
|
4012
4015
|
epoch: decodeId(o.epoch),
|
|
4013
4016
|
status: oneOf(o.status, statuses),
|
|
4014
4017
|
notice: text(o.notice, 1024),
|
|
4018
|
+
omitted: {
|
|
4019
|
+
thinking: omitted ? bool(omitted.thinking) : false,
|
|
4020
|
+
media: omitted ? bool(omitted.media) : false,
|
|
4021
|
+
other: omitted ? bool(omitted.other) : false
|
|
4022
|
+
},
|
|
4015
4023
|
items: list(o.items, 256, (v2) => {
|
|
4016
4024
|
const i = closed(v2, ["id", "role", "text", "name", "args", "error"]);
|
|
4017
4025
|
return {
|
|
@@ -10285,7 +10293,7 @@ async function createGateway(value, hostUrl, source) {
|
|
|
10285
10293
|
const input = decodeGatewayInput(value), store = new GatewayStore(input.serverConfig, input.stateHome);
|
|
10286
10294
|
const web = loadWebAssets(source?.webDirectory);
|
|
10287
10295
|
const build2 = {
|
|
10288
|
-
contractHash: "
|
|
10296
|
+
contractHash: "83a2720c0a5a61f9e18e4f67e9738f184dee61cf07e75d9b98b5728577daaa6d",
|
|
10289
10297
|
assets: {
|
|
10290
10298
|
sourceHash: web.manifest.sourceHash,
|
|
10291
10299
|
contractHash: web.manifest.contractHash,
|
|
@@ -21944,6 +21952,22 @@ function argumentsData(value, secrets) {
|
|
|
21944
21952
|
throw new Error("Unsupported context arguments");
|
|
21945
21953
|
return parseWireJson(source, 64 * 1024);
|
|
21946
21954
|
}
|
|
21955
|
+
function own(value, key2) {
|
|
21956
|
+
const d = value && typeof value === "object" ? Object.getOwnPropertyDescriptor(value, key2) : undefined;
|
|
21957
|
+
if (!d || !("value" in d))
|
|
21958
|
+
throw new Error("Invalid usage");
|
|
21959
|
+
return d.value;
|
|
21960
|
+
}
|
|
21961
|
+
function counts(value, keys3) {
|
|
21962
|
+
const out = Object.create(null);
|
|
21963
|
+
for (const key2 of keys3) {
|
|
21964
|
+
const n = own(value, key2);
|
|
21965
|
+
if (typeof n !== "number" || !Number.isFinite(n) || n < 0)
|
|
21966
|
+
throw new Error("Invalid usage");
|
|
21967
|
+
out[key2] = n;
|
|
21968
|
+
}
|
|
21969
|
+
return out;
|
|
21970
|
+
}
|
|
21947
21971
|
function conversationMessages(messages, secrets = []) {
|
|
21948
21972
|
return list(messages, 4096, (message) => {
|
|
21949
21973
|
if (!message || typeof message !== "object")
|
|
@@ -21973,27 +21997,20 @@ function conversationMessages(messages, secrets = []) {
|
|
|
21973
21997
|
toolName: clean(message.toolName, secrets, 128),
|
|
21974
21998
|
isError: message.isError === true
|
|
21975
21999
|
};
|
|
21976
|
-
const usage =
|
|
22000
|
+
const usage = counts(message.usage, [
|
|
21977
22001
|
"input",
|
|
21978
22002
|
"output",
|
|
21979
22003
|
"cacheRead",
|
|
21980
22004
|
"cacheWrite",
|
|
21981
|
-
"totalTokens"
|
|
21982
|
-
"cost"
|
|
22005
|
+
"totalTokens"
|
|
21983
22006
|
]);
|
|
21984
|
-
|
|
22007
|
+
usage.cost = counts(own(message.usage, "cost"), [
|
|
21985
22008
|
"input",
|
|
21986
22009
|
"output",
|
|
21987
22010
|
"cacheRead",
|
|
21988
22011
|
"cacheWrite",
|
|
21989
22012
|
"total"
|
|
21990
22013
|
]);
|
|
21991
|
-
for (const value of [
|
|
21992
|
-
...Object.values(usage).filter((v) => typeof v !== "object"),
|
|
21993
|
-
...Object.values(cost)
|
|
21994
|
-
])
|
|
21995
|
-
if (typeof value !== "number" || !Number.isFinite(value) || value < 0)
|
|
21996
|
-
throw new Error("Invalid usage");
|
|
21997
22014
|
return {
|
|
21998
22015
|
role: role2,
|
|
21999
22016
|
timestamp,
|
|
@@ -24852,7 +24869,7 @@ class TaskActions {
|
|
|
24852
24869
|
const graph = action.kind === "start" ? plan?.graph ?? this.defaultGraph(selected2.record, selected2.identity, expected.model) : null;
|
|
24853
24870
|
if (graph && hash2(canonicalJson(graph)) !== expected.task.graphIdentity)
|
|
24854
24871
|
throw new ContractError("stale");
|
|
24855
|
-
let
|
|
24872
|
+
let own3 = {
|
|
24856
24873
|
revision: selected2.record.revision,
|
|
24857
24874
|
identity: selected2.identity
|
|
24858
24875
|
};
|
|
@@ -24882,7 +24899,7 @@ class TaskActions {
|
|
|
24882
24899
|
try {
|
|
24883
24900
|
this.assertChoice(expected);
|
|
24884
24901
|
const latest = h.coordination.store.loadSnapshot(action.taskId);
|
|
24885
|
-
return latest?.identity ===
|
|
24902
|
+
return latest?.identity === own3.identity && latest.record.revision === own3.revision && this.sources.current();
|
|
24886
24903
|
} catch {
|
|
24887
24904
|
return false;
|
|
24888
24905
|
}
|
|
@@ -24910,7 +24927,7 @@ class TaskActions {
|
|
|
24910
24927
|
});
|
|
24911
24928
|
if (publication.status !== "published" || !publication.observed)
|
|
24912
24929
|
throw new ContractError("conflict");
|
|
24913
|
-
|
|
24930
|
+
own3 = publication.observed;
|
|
24914
24931
|
}
|
|
24915
24932
|
});
|
|
24916
24933
|
accepted2.activate(work);
|
|
@@ -25149,6 +25166,11 @@ import { dirname as dirname14, join as join22 } from "node:path";
|
|
|
25149
25166
|
var TURN_BYTES = 384 * 1024;
|
|
25150
25167
|
var META_BYTES = 64 * 1024;
|
|
25151
25168
|
var SESSION_LIMIT = 200;
|
|
25169
|
+
var OMITTED_FLAG = {
|
|
25170
|
+
"hidden-thinking": "thinking",
|
|
25171
|
+
binary: "media",
|
|
25172
|
+
unsupported: "other"
|
|
25173
|
+
};
|
|
25152
25174
|
|
|
25153
25175
|
class ConversationCapture {
|
|
25154
25176
|
turn;
|
|
@@ -25242,8 +25264,8 @@ class ConversationCapture {
|
|
|
25242
25264
|
item.error = e.isError;
|
|
25243
25265
|
} else if (e.kind === "worker-failure")
|
|
25244
25266
|
this.turn.notice = `worker-failure: ${e.code}`;
|
|
25245
|
-
else if (e.kind === "omitted-block")
|
|
25246
|
-
this.turn.
|
|
25267
|
+
else if (e.kind === "omitted-block" && e.block.owner.kind !== "context" && e.block.owner.kind !== "handoff")
|
|
25268
|
+
this.turn.omitted[OMITTED_FLAG[e.block.reason]] = true;
|
|
25247
25269
|
if ([...this.details.values()].reduce((size, detail) => size + Buffer.byteLength(detail.text) + detail.sanitizer.retainedBytes, 0) > TURN_BYTES)
|
|
25248
25270
|
throw new ContractError("capacity");
|
|
25249
25271
|
canonicalJson(this.turn, TURN_BYTES);
|
|
@@ -25500,6 +25522,7 @@ class Conversations {
|
|
|
25500
25522
|
epoch: input.model.epoch,
|
|
25501
25523
|
status: "queued",
|
|
25502
25524
|
notice: "",
|
|
25525
|
+
omitted: { thinking: false, media: false, other: false },
|
|
25503
25526
|
items: [
|
|
25504
25527
|
{
|
|
25505
25528
|
id: "user",
|
|
@@ -25925,7 +25948,7 @@ function refuseAt(stage, step) {
|
|
|
25925
25948
|
}
|
|
25926
25949
|
}
|
|
25927
25950
|
async function createServiceHost(value, sourceBuild) {
|
|
25928
|
-
const embedded = "
|
|
25951
|
+
const embedded = "83a2720c0a5a61f9e18e4f67e9738f184dee61cf07e75d9b98b5728577daaa6d";
|
|
25929
25952
|
if (embedded && sourceBuild)
|
|
25930
25953
|
throw new ContractError("unsupported-context");
|
|
25931
25954
|
const contractHash = decodeHash(embedded ?? sourceBuild?.contractHash);
|