@abelxiaoxing/cadence 1.0.4 → 1.0.6
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/config/.env.example +18 -14
- package/package.json +1 -1
- package/src/child-session.ts +28 -15
- package/src/parent-provider.ts +3 -0
package/config/.env.example
CHANGED
|
@@ -1,29 +1,33 @@
|
|
|
1
1
|
# Copy to <project>/.pi/cadence/.env or ~/.pi/agent/cadence/.env.
|
|
2
2
|
# The project file wins as a whole file; values are not merged or interpolated.
|
|
3
3
|
|
|
4
|
-
# Optional Subagent endpoint.
|
|
5
|
-
#
|
|
4
|
+
# Optional custom Subagent endpoint. To enable it, set all required values.
|
|
5
|
+
# Any non-empty key commits the whole layer; partial/invalid layers fail closed.
|
|
6
6
|
SUBAGENT_API_URL=
|
|
7
7
|
SUBAGENT_API_KEY=
|
|
8
8
|
SUBAGENT_MODEL=
|
|
9
|
-
#
|
|
10
|
-
SUBAGENT_API=
|
|
11
|
-
#
|
|
12
|
-
SUBAGENT_CONTEXT_WINDOW=
|
|
13
|
-
SUBAGENT_MAX_TOKENS=
|
|
9
|
+
# Optional dialect: openai-completions (default), openai-responses,or anthropic-messages.
|
|
10
|
+
# SUBAGENT_API=openai-completions
|
|
11
|
+
# Optional bounds; internal defaults are 256000 and 128000 respectively.
|
|
12
|
+
# SUBAGENT_CONTEXT_WINDOW=256000
|
|
13
|
+
# SUBAGENT_MAX_TOKENS=128000
|
|
14
14
|
|
|
15
15
|
# Per-role layers use the same six suffixes and override the global layer whole:
|
|
16
16
|
# SUBAGENT_<ROLE>_<SUFFIX>, where ROLE is DESIGN_EXPLORER, CONTRACT_REVIEWER,
|
|
17
17
|
# IMPLEMENTATION_WORKER, or DIAGNOSIS_WORKER. Partial/invalid layers fail closed.
|
|
18
18
|
|
|
19
|
-
|
|
20
|
-
|
|
19
|
+
# Context7 works anonymously with its default URL. Uncomment the API key for
|
|
20
|
+
# authenticated access, or the URL only when overriding the default endpoint.
|
|
21
|
+
# CONTEXT7_API_URL=https://context7.com/api/v2
|
|
22
|
+
# CONTEXT7_API_KEY=
|
|
21
23
|
|
|
24
|
+
# Required when using the Grok search skill.
|
|
22
25
|
GROK_API_URL=https://api.x.ai/v1
|
|
23
26
|
GROK_API_KEY=
|
|
24
|
-
|
|
27
|
+
# Optional model override.
|
|
28
|
+
# GROK_MODEL=grok-4.20-non-reasoning
|
|
25
29
|
|
|
26
|
-
# Tavily is enabled by default when TAVILY_API_KEY is set; set to false to opt out.
|
|
27
|
-
TAVILY_ENABLED=true
|
|
28
|
-
TAVILY_API_URL=https://api.tavily.com
|
|
29
|
-
TAVILY_API_KEY=
|
|
30
|
+
# Optional Tavily integration. It is enabled by default when TAVILY_API_KEY is set; set TAVILY_ENABLED to false to opt out.
|
|
31
|
+
# TAVILY_ENABLED=true
|
|
32
|
+
# TAVILY_API_URL=https://api.tavily.com
|
|
33
|
+
# TAVILY_API_KEY=
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@abelxiaoxing/cadence",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.6",
|
|
4
4
|
"description": "Prompts, skills, and a private orchestration extension exposing the Abel four-stage workflow (/abel-init, /abel-design, /abel-implement, /abel-diagnose) with package-owned professional Agents.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
package/src/child-session.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
|
-
import type { Model, Usage } from "@earendil-works/pi-ai";
|
|
2
|
+
import type { AssistantMessage, Model, Usage } from "@earendil-works/pi-ai";
|
|
3
3
|
import {
|
|
4
4
|
createAgentSession,
|
|
5
5
|
defineTool,
|
|
@@ -137,6 +137,26 @@ function wrapScopedTools(
|
|
|
137
137
|
|
|
138
138
|
export type ChildFailureKind = "failed" | "cancelled" | "timed-out";
|
|
139
139
|
|
|
140
|
+
function finalDeliveryContent(message: AssistantMessage | undefined) {
|
|
141
|
+
return (
|
|
142
|
+
message?.content.filter(
|
|
143
|
+
(content) =>
|
|
144
|
+
content.type !== "thinking" &&
|
|
145
|
+
!(content.type === "text" && content.text.trim().length === 0),
|
|
146
|
+
) ?? []
|
|
147
|
+
);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
function isSingleStructuralSubmit(message: AssistantMessage | undefined) {
|
|
151
|
+
const content = finalDeliveryContent(message);
|
|
152
|
+
return (
|
|
153
|
+
message?.role === "assistant" &&
|
|
154
|
+
content.length === 1 &&
|
|
155
|
+
content[0]?.type === "toolCall" &&
|
|
156
|
+
content[0].name === "abel_submit_result"
|
|
157
|
+
);
|
|
158
|
+
}
|
|
159
|
+
|
|
140
160
|
export type ChildSessionResult =
|
|
141
161
|
| {
|
|
142
162
|
ok: true;
|
|
@@ -218,17 +238,15 @@ export async function runChildSession(input: {
|
|
|
218
238
|
let finalCategory: FinalCategory;
|
|
219
239
|
if (!last) {
|
|
220
240
|
finalCategory = "no-final-assistant";
|
|
221
|
-
} else if (
|
|
222
|
-
last.content.length === 1 &&
|
|
223
|
-
last.content[0].type === "toolCall" &&
|
|
224
|
-
last.content[0].name === "abel_submit_result"
|
|
225
|
-
) {
|
|
241
|
+
} else if (isSingleStructuralSubmit(last)) {
|
|
226
242
|
finalCategory =
|
|
227
243
|
submit.getAttempts() > 1 ? "multiple-submit" : "single-submit-only";
|
|
228
|
-
} else if (last.content.length === 1 && last.content[0].type === "text") {
|
|
229
|
-
finalCategory = "text-only";
|
|
230
244
|
} else {
|
|
231
|
-
|
|
245
|
+
const content = finalDeliveryContent(last);
|
|
246
|
+
finalCategory =
|
|
247
|
+
content.length === 1 && content[0]?.type === "text"
|
|
248
|
+
? "text-only"
|
|
249
|
+
: "mixed";
|
|
232
250
|
}
|
|
233
251
|
return {
|
|
234
252
|
finalCategory,
|
|
@@ -336,12 +354,7 @@ export async function runChildSession(input: {
|
|
|
336
354
|
}
|
|
337
355
|
const assistants = session.messages.filter((m) => m.role === "assistant");
|
|
338
356
|
const final = assistants.at(-1);
|
|
339
|
-
if (
|
|
340
|
-
final?.role !== "assistant" ||
|
|
341
|
-
final.content.length !== 1 ||
|
|
342
|
-
final.content[0]?.type !== "toolCall" ||
|
|
343
|
-
final.content[0]?.name !== "abel_submit_result"
|
|
344
|
-
) {
|
|
357
|
+
if (!isSingleStructuralSubmit(final)) {
|
|
345
358
|
disposeOnce();
|
|
346
359
|
return {
|
|
347
360
|
ok: false,
|
package/src/parent-provider.ts
CHANGED
|
@@ -82,6 +82,9 @@ function customSubagentModel(endpoint: SubagentEndpoint): Model<string> {
|
|
|
82
82
|
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },
|
|
83
83
|
contextWindow: endpoint.contextWindow,
|
|
84
84
|
maxTokens: endpoint.maxTokens,
|
|
85
|
+
...(endpoint.dialect === "openai-completions"
|
|
86
|
+
? { compat: { supportsDeveloperRole: false } }
|
|
87
|
+
: {}),
|
|
85
88
|
} as Model<string>;
|
|
86
89
|
}
|
|
87
90
|
|