ahead-pi 0.8.0 → 0.8.1
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/examples.ts +24 -8
- package/src/index.ts +15 -3
package/package.json
CHANGED
package/src/examples.ts
CHANGED
|
@@ -8,7 +8,14 @@ export interface FieldExamplesInput {
|
|
|
8
8
|
fields: string[];
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
-
const EXAMPLES_TIMEOUT_MS =
|
|
11
|
+
const EXAMPLES_TIMEOUT_MS = 12_000;
|
|
12
|
+
|
|
13
|
+
export type FieldExamplesSkipped = "no-model" | "no-auth" | "failed";
|
|
14
|
+
|
|
15
|
+
export interface FieldExamplesResult {
|
|
16
|
+
examples?: string[][];
|
|
17
|
+
skipped?: FieldExamplesSkipped;
|
|
18
|
+
}
|
|
12
19
|
|
|
13
20
|
/**
|
|
14
21
|
* Draft two inspiration-only example lines per artifact field.
|
|
@@ -21,10 +28,10 @@ const EXAMPLES_TIMEOUT_MS = 25_000;
|
|
|
21
28
|
export async function draftFieldExamples(
|
|
22
29
|
ctx: ExtensionCommandContext,
|
|
23
30
|
input: FieldExamplesInput,
|
|
24
|
-
): Promise<
|
|
31
|
+
): Promise<FieldExamplesResult> {
|
|
25
32
|
const model = ctx.model;
|
|
26
33
|
if (!model) {
|
|
27
|
-
return
|
|
34
|
+
return { skipped: "no-model" };
|
|
28
35
|
}
|
|
29
36
|
|
|
30
37
|
const prompt = [
|
|
@@ -46,9 +53,13 @@ export async function draftFieldExamples(
|
|
|
46
53
|
].join("\n");
|
|
47
54
|
|
|
48
55
|
try {
|
|
56
|
+
// getProviderAuth returning undefined means no usable credential of any
|
|
57
|
+
// kind could be resolved — only then is a heads-up accurate. A resolved
|
|
58
|
+
// auth object without an apiKey (e.g. OAuth) may still succeed through
|
|
59
|
+
// the adapter's own credential resolution, so we attempt the call.
|
|
49
60
|
const auth = await ctx.modelRegistry.getProviderAuth(model.provider);
|
|
50
61
|
if (!auth) {
|
|
51
|
-
return
|
|
62
|
+
return { skipped: "no-auth" };
|
|
52
63
|
}
|
|
53
64
|
const message = await Promise.race([
|
|
54
65
|
completeSimple(
|
|
@@ -74,11 +85,15 @@ export async function draftFieldExamples(
|
|
|
74
85
|
}),
|
|
75
86
|
]);
|
|
76
87
|
if (!message) {
|
|
77
|
-
return
|
|
88
|
+
return { skipped: "failed" };
|
|
89
|
+
}
|
|
90
|
+
const examples = parseExampleLines(message, input.fields.length);
|
|
91
|
+
if (!examples) {
|
|
92
|
+
return { skipped: "failed" };
|
|
78
93
|
}
|
|
79
|
-
return
|
|
94
|
+
return { examples };
|
|
80
95
|
} catch {
|
|
81
|
-
return
|
|
96
|
+
return { skipped: "failed" };
|
|
82
97
|
}
|
|
83
98
|
}
|
|
84
99
|
|
|
@@ -99,7 +114,8 @@ function textBlocks(content: unknown): string[] {
|
|
|
99
114
|
return blocks;
|
|
100
115
|
}
|
|
101
116
|
|
|
102
|
-
|
|
117
|
+
/** Exported for unit testing; the wire shape is validated defensively at runtime. */
|
|
118
|
+
export function parseExampleLines(message: unknown, fieldCount: number): string[][] | undefined {
|
|
103
119
|
const text = textBlocks(isRecord(message) ? message.content : undefined).join("\n");
|
|
104
120
|
|
|
105
121
|
const perField: string[][] = Array.from({ length: fieldCount }, () => []);
|
package/src/index.ts
CHANGED
|
@@ -1603,15 +1603,27 @@ async function recordHumanArtifact(
|
|
|
1603
1603
|
const prompts = promptsForArtifact(state.workflow_id, state.phase.id, artifact.kind);
|
|
1604
1604
|
let template = await humanArtifactTemplate(store, state, run, artifact.kind, artifact.title);
|
|
1605
1605
|
if (ctx.hasUI && artifact.kind !== "review-disposition" && prompts.length > 0) {
|
|
1606
|
-
|
|
1606
|
+
if (ctx.model) {
|
|
1607
|
+
ctx.ui.notify("Drafting two example prompts per field (inspiration only)…", "info");
|
|
1608
|
+
}
|
|
1609
|
+
const draft = await draftFieldExamples(ctx, {
|
|
1607
1610
|
workflowTitle: engine.getWorkflow(state.workflow_id).title,
|
|
1608
1611
|
phaseTitle: state.phase.title,
|
|
1609
1612
|
runTitle: run.title,
|
|
1610
1613
|
fields: prompts,
|
|
1611
1614
|
});
|
|
1612
|
-
if (examples) {
|
|
1613
|
-
template = insertFieldExamples(template, examples);
|
|
1615
|
+
if (draft.examples) {
|
|
1616
|
+
template = insertFieldExamples(template, draft.examples);
|
|
1617
|
+
} else if (draft.skipped === "no-auth") {
|
|
1618
|
+
ctx.ui.notify(
|
|
1619
|
+
"Example prompts unavailable: no usable model credential could be resolved for this session.",
|
|
1620
|
+
"info",
|
|
1621
|
+
);
|
|
1622
|
+
} else if (draft.skipped === "no-model") {
|
|
1623
|
+
ctx.ui.notify("Example prompts unavailable: no active model in this session.", "info");
|
|
1614
1624
|
}
|
|
1625
|
+
// "failed" (timeout, unparseable output, transient error) stays silent:
|
|
1626
|
+
// the plain template is the fallback and needs no apology.
|
|
1615
1627
|
}
|
|
1616
1628
|
let content = await ctx.ui.editor(
|
|
1617
1629
|
`AHEAD mode · ${artifact.title} · write in your own words`,
|