imprint-mcp 0.7.0 → 0.7.2
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/README.md +66 -2
- package/package.json +1 -1
- package/prompts/auth-compile-agent.md +173 -22
- package/prompts/compile-agent.md +45 -8
- package/prompts/component-recovery.md +40 -0
- package/prompts/master-teach-decision.md +28 -3
- package/prompts/master-teach-focused-planner.md +18 -5
- package/src/cli.ts +26 -18
- package/src/imprint/agent-tool.ts +15 -0
- package/src/imprint/agent.ts +2 -11
- package/src/imprint/audit.ts +35 -13
- package/src/imprint/auth-browser-discovery.ts +276 -0
- package/src/imprint/auth-compile-agent.ts +513 -224
- package/src/imprint/auth-compile-tools.ts +213 -25
- package/src/imprint/auth-discovery-evidence.ts +81 -0
- package/src/imprint/auth-plan.ts +28 -0
- package/src/imprint/auth-verifier.ts +234 -20
- package/src/imprint/authentication-interaction.ts +137 -0
- package/src/imprint/backend-ladder.ts +271 -43
- package/src/imprint/build-plan.ts +2 -22
- package/src/imprint/cdp-browser-fetch.ts +242 -60
- package/src/imprint/chromium.ts +93 -29
- package/src/imprint/claude-cli-compile.ts +2 -0
- package/src/imprint/codex-cli-compile.ts +99 -46
- package/src/imprint/compile-agent-types.ts +9 -5
- package/src/imprint/compile-agent.ts +33 -0
- package/src/imprint/compile-tool-executor.ts +783 -0
- package/src/imprint/compile-tools.ts +42 -9
- package/src/imprint/compile-verification.ts +2 -0
- package/src/imprint/compile.ts +3 -0
- package/src/imprint/compiler-log.ts +16 -0
- package/src/imprint/component-recovery.ts +120 -0
- package/src/imprint/cookie-jar.ts +117 -7
- package/src/imprint/credential-extract.ts +9 -2
- package/src/imprint/credential-lock.ts +147 -0
- package/src/imprint/credential-observation.ts +261 -0
- package/src/imprint/credential-store.ts +284 -44
- package/src/imprint/live-component-recovery.ts +73 -0
- package/src/imprint/llm.ts +4 -3
- package/src/imprint/log.ts +16 -1
- package/src/imprint/login.ts +9 -0
- package/src/imprint/master-teach-agent-contracts.ts +40 -3
- package/src/imprint/master-teach-agents.ts +229 -14
- package/src/imprint/master-teach-checks.ts +8 -1
- package/src/imprint/master-teach-controller.ts +681 -138
- package/src/imprint/master-teach-prompt-projections.ts +2 -0
- package/src/imprint/mcp-cdp-sessions.ts +7 -2
- package/src/imprint/mcp-compile-server.ts +62 -850
- package/src/imprint/mcp-server.ts +667 -91
- package/src/imprint/mcp-session-recovery.ts +167 -0
- package/src/imprint/native-teach-agents.ts +232 -108
- package/src/imprint/runtime.ts +416 -47
- package/src/imprint/stealth-chromium.ts +67 -7
- package/src/imprint/teach-browser-resources.ts +88 -0
- package/src/imprint/teach-stage-progress.ts +38 -0
- package/src/imprint/terminal-user-prompt.ts +42 -0
- package/src/imprint/types.ts +51 -18
- package/src/imprint/user-interaction.ts +836 -0
|
@@ -75,6 +75,11 @@ import {
|
|
|
75
75
|
SharedResearchExchangeSchema,
|
|
76
76
|
type TeachResearchMemory,
|
|
77
77
|
} from './teach-research-memory.ts';
|
|
78
|
+
import {
|
|
79
|
+
AgentInteractionSchema,
|
|
80
|
+
USER_INTERACTION_INSTRUCTIONS,
|
|
81
|
+
requestAgentInteraction,
|
|
82
|
+
} from './user-interaction.ts';
|
|
78
83
|
export * from './master-teach-agent-contracts.ts';
|
|
79
84
|
export * from './master-teach-prompt-projections.ts';
|
|
80
85
|
export type { MasterTeachAnalyzer } from './native-agent-pass.ts';
|
|
@@ -1767,16 +1772,8 @@ function masterOutputSchema(input: MasterDecisionInput) {
|
|
|
1767
1772
|
if (input.phase === 'discovery' && output.recallToolNames.length > 0)
|
|
1768
1773
|
issue(ctx, ['recallToolNames'], 'initial discovery cannot recall an existing tool');
|
|
1769
1774
|
const researchFollowUps = output.researchFollowUps ?? [];
|
|
1770
|
-
if (
|
|
1771
|
-
researchFollowUps
|
|
1772
|
-
input.decisionPurpose !== 'research_review' &&
|
|
1773
|
-
!input.current?.snapshot
|
|
1774
|
-
)
|
|
1775
|
-
issue(
|
|
1776
|
-
ctx,
|
|
1777
|
-
['researchFollowUps'],
|
|
1778
|
-
'research follow-ups require research review or a current execution snapshot',
|
|
1779
|
-
);
|
|
1775
|
+
if (researchFollowUps.length > 0 && !input.current)
|
|
1776
|
+
issue(ctx, ['researchFollowUps'], 'research follow-ups require an existing teaching plan');
|
|
1780
1777
|
if (input.decisionPurpose === 'research_review' && output.recallToolNames.length > 0)
|
|
1781
1778
|
issue(ctx, ['recallToolNames'], 'research review directs researchers, not compilers');
|
|
1782
1779
|
const currentToolNames = new Set(
|
|
@@ -2179,6 +2176,7 @@ type Role =
|
|
|
2179
2176
|
| 'focused planner'
|
|
2180
2177
|
| 'API researcher'
|
|
2181
2178
|
| 'master decision'
|
|
2179
|
+
| 'component recovery'
|
|
2182
2180
|
| 'baseline MVP reviewer'
|
|
2183
2181
|
| 'parameter advisor'
|
|
2184
2182
|
| 'completion reviewer'
|
|
@@ -2450,6 +2448,7 @@ async function request<S extends z.ZodTypeAny>(options: {
|
|
|
2450
2448
|
validation: unknown;
|
|
2451
2449
|
schema: S;
|
|
2452
2450
|
agent: MasterTeachAgentOptions;
|
|
2451
|
+
allowInteractions?: boolean;
|
|
2453
2452
|
}): Promise<z.output<S>> {
|
|
2454
2453
|
const memory = options.agent.sharedResearch;
|
|
2455
2454
|
const author = `${options.agent.conversationPrefix ?? ''}${options.conversationKey}`;
|
|
@@ -2459,7 +2458,7 @@ async function request<S extends z.ZodTypeAny>(options: {
|
|
|
2459
2458
|
input: options.input,
|
|
2460
2459
|
validation: options.validation,
|
|
2461
2460
|
});
|
|
2462
|
-
const system = `${readFileSync(join(PROMPTS, options.prompt), 'utf8')}${memory ? SHARED_RESEARCH_INSTRUCTIONS : ''}\n\nWhen supplied, runTiming gives the host's current time and remaining shared run budget at this turn. Use it to choose a useful MVP and proportionate next steps, leaving time for planning, compilation, live verification, repair, and publication. These are time facts, not per-tool attempt limits or permission to weaken proof. Strategy remains yours.`;
|
|
2461
|
+
const system = `${readFileSync(join(PROMPTS, options.prompt), 'utf8')}${memory ? SHARED_RESEARCH_INSTRUCTIONS : ''}${USER_INTERACTION_INSTRUCTIONS}\n\nWhen supplied, runTiming gives the host's current time and remaining shared run budget at this turn. Use it to choose a useful MVP and proportionate next steps, leaving time for planning, compilation, live verification, repair, and publication. These are time facts, not per-tool attempt limits or permission to weaken proof. Strategy remains yours.`;
|
|
2463
2462
|
const startedAt = Date.now();
|
|
2464
2463
|
const roleExpiresAt =
|
|
2465
2464
|
options.agent.timeoutMs === undefined ? undefined : startedAt + options.agent.timeoutMs;
|
|
@@ -2529,6 +2528,31 @@ async function request<S extends z.ZodTypeAny>(options: {
|
|
|
2529
2528
|
while (true) {
|
|
2530
2529
|
try {
|
|
2531
2530
|
const decoded = parse(options.role, response.text, z.record(z.unknown()), attempt);
|
|
2531
|
+
if (decoded.interaction !== undefined) {
|
|
2532
|
+
if (options.allowInteractions === false)
|
|
2533
|
+
throw new SemanticAgentOutputError(
|
|
2534
|
+
options.role,
|
|
2535
|
+
[
|
|
2536
|
+
'Return the recovery decision directly; the host dispatches the selected component owner.',
|
|
2537
|
+
],
|
|
2538
|
+
attempt,
|
|
2539
|
+
);
|
|
2540
|
+
const interaction = parse(
|
|
2541
|
+
options.role,
|
|
2542
|
+
JSON.stringify(decoded),
|
|
2543
|
+
z.object({ interaction: AgentInteractionSchema }).strict(),
|
|
2544
|
+
attempt,
|
|
2545
|
+
).interaction;
|
|
2546
|
+
const interactionResult = await requestAgentInteraction(interaction, signal);
|
|
2547
|
+
response = await analyze({
|
|
2548
|
+
...(retainedCodexConversation ? {} : { originalInput: options.input }),
|
|
2549
|
+
validationContext: options.validation,
|
|
2550
|
+
interactionResult,
|
|
2551
|
+
instruction:
|
|
2552
|
+
'Continue the same role. User input and authentication results do not prove the data operation. Cancellation or unavailable input is not approval.',
|
|
2553
|
+
});
|
|
2554
|
+
continue;
|
|
2555
|
+
}
|
|
2532
2556
|
const { sharedResearch, ...decision } = decoded;
|
|
2533
2557
|
let exchange: z.infer<typeof SharedResearchExchangeSchema> | undefined;
|
|
2534
2558
|
if (sharedResearch !== undefined) {
|
|
@@ -2645,6 +2669,61 @@ export async function requestToolSelectionAdvice(
|
|
|
2645
2669
|
agent,
|
|
2646
2670
|
});
|
|
2647
2671
|
}
|
|
2672
|
+
/** Keep exact own/dependency research in the reading path and retain other
|
|
2673
|
+
* operations as a small index. The master still owns every complete handoff. */
|
|
2674
|
+
export function focusedPlannerResearchContext(
|
|
2675
|
+
input: Pick<
|
|
2676
|
+
FocusedPlannerInput,
|
|
2677
|
+
| 'tool'
|
|
2678
|
+
| 'availableProducers'
|
|
2679
|
+
| 'siblingToolEvidence'
|
|
2680
|
+
| 'incomingChainEdges'
|
|
2681
|
+
| 'outgoingChainEdges'
|
|
2682
|
+
| 'apiResearch'
|
|
2683
|
+
| 'apiResearchIndex'
|
|
2684
|
+
>,
|
|
2685
|
+
memory?: TeachResearchMemory,
|
|
2686
|
+
): Pick<FocusedPlannerInput, 'apiResearch' | 'apiResearchIndex'> {
|
|
2687
|
+
const relevantNames = new Set([
|
|
2688
|
+
input.tool.candidate.toolName,
|
|
2689
|
+
...input.tool.candidate.dependsOnTools,
|
|
2690
|
+
]);
|
|
2691
|
+
const namesById = new Map([
|
|
2692
|
+
[input.tool.id, input.tool.candidate.toolName],
|
|
2693
|
+
...input.availableProducers.map(({ toolId, toolName }) => [toolId, toolName] as const),
|
|
2694
|
+
...input.siblingToolEvidence.map(({ toolId, toolName }) => [toolId, toolName] as const),
|
|
2695
|
+
]);
|
|
2696
|
+
for (const edge of [...input.incomingChainEdges, ...input.outgoingChainEdges]) {
|
|
2697
|
+
for (const toolId of [edge.producerToolId, edge.consumerToolId]) {
|
|
2698
|
+
const name = namesById.get(toolId);
|
|
2699
|
+
if (name) relevantNames.add(name);
|
|
2700
|
+
}
|
|
2701
|
+
}
|
|
2702
|
+
const index = new Map((input.apiResearchIndex ?? []).map((entry) => [entry.toolName, entry]));
|
|
2703
|
+
for (const handoff of input.apiResearch ?? []) {
|
|
2704
|
+
const observation = handoff.observation ?? handoff.observations?.at(-1);
|
|
2705
|
+
const handoffRef = memory?.remember(handoff) ?? index.get(handoff.toolName)?.handoffRef;
|
|
2706
|
+
index.set(handoff.toolName, {
|
|
2707
|
+
toolName: handoff.toolName,
|
|
2708
|
+
researchInputsSha256: handoff.researchInputsSha256,
|
|
2709
|
+
status: handoff.status,
|
|
2710
|
+
summary: handoff.summary.slice(0, 400),
|
|
2711
|
+
...(observation
|
|
2712
|
+
? {
|
|
2713
|
+
observationId: observation.id,
|
|
2714
|
+
executionMechanism: observation.executionMechanism,
|
|
2715
|
+
resultOk: observation.result.ok,
|
|
2716
|
+
}
|
|
2717
|
+
: {}),
|
|
2718
|
+
...(handoffRef ? { handoffRef } : {}),
|
|
2719
|
+
});
|
|
2720
|
+
}
|
|
2721
|
+
return {
|
|
2722
|
+
apiResearch: (input.apiResearch ?? []).filter(({ toolName }) => relevantNames.has(toolName)),
|
|
2723
|
+
apiResearchIndex: [...index.values()],
|
|
2724
|
+
};
|
|
2725
|
+
}
|
|
2726
|
+
|
|
2648
2727
|
export async function requestFocusedPlan(
|
|
2649
2728
|
input: FocusedPlannerInput,
|
|
2650
2729
|
agent: MasterTeachAgentOptions = {},
|
|
@@ -2654,7 +2733,7 @@ export async function requestFocusedPlan(
|
|
|
2654
2733
|
role: 'focused planner',
|
|
2655
2734
|
conversationKey: `tool:${checked.tool.candidate.toolName}:planner`,
|
|
2656
2735
|
prompt: 'master-teach-focused-planner.md',
|
|
2657
|
-
input: checked,
|
|
2736
|
+
input: { ...checked, ...focusedPlannerResearchContext(checked, agent.sharedResearch) },
|
|
2658
2737
|
validation: {
|
|
2659
2738
|
binding: focusedPlannerBinding(checked),
|
|
2660
2739
|
recordingIndex: checked.recordingIndex,
|
|
@@ -2664,6 +2743,13 @@ export async function requestFocusedPlan(
|
|
|
2664
2743
|
agent,
|
|
2665
2744
|
});
|
|
2666
2745
|
}
|
|
2746
|
+
// Native research passes wrap a new analyzer around the same retained child.
|
|
2747
|
+
// Key native delivery by family + conversation rather than that short-lived wrapper.
|
|
2748
|
+
const researchSiblingDelivery = new WeakMap<
|
|
2749
|
+
object,
|
|
2750
|
+
Map<string, { runId: string; handoffs: Map<string, string> }>
|
|
2751
|
+
>();
|
|
2752
|
+
|
|
2667
2753
|
export async function requestApiResearchStep(
|
|
2668
2754
|
input: ApiResearchInput,
|
|
2669
2755
|
agent: MasterTeachAgentOptions = {},
|
|
@@ -2671,11 +2757,41 @@ export async function requestApiResearchStep(
|
|
|
2671
2757
|
) {
|
|
2672
2758
|
const checked = ApiResearchInputValidationSchema.parse(input);
|
|
2673
2759
|
const latestObservation = checked.observations.at(-1);
|
|
2760
|
+
const conversation = `${agent.conversationPrefix ?? ''}tool:${checked.tool.candidate.toolName}:api-researcher`;
|
|
2761
|
+
const retainedOwner =
|
|
2762
|
+
agent.provider === 'codex-cli' ? (currentNativeTeachAgents() ?? agent.analyzer) : undefined;
|
|
2763
|
+
const priorDelivery = retainedOwner
|
|
2764
|
+
? researchSiblingDelivery.get(retainedOwner)?.get(conversation)
|
|
2765
|
+
: undefined;
|
|
2766
|
+
const previousSiblings =
|
|
2767
|
+
priorDelivery?.runId === checked.run.runId ? priorDelivery.handoffs : undefined;
|
|
2768
|
+
const memory = agent.sharedResearch;
|
|
2769
|
+
const followUp =
|
|
2770
|
+
retainedTurnDelta?.kind === 'master_follow_up' && retainedOwner && memory
|
|
2771
|
+
? {
|
|
2772
|
+
...retainedTurnDelta.followUp,
|
|
2773
|
+
siblingResearch: retainedTurnDelta.followUp.siblingResearch.filter(
|
|
2774
|
+
(handoff) => previousSiblings?.get(handoff.toolName) !== digest(handoff),
|
|
2775
|
+
),
|
|
2776
|
+
retainedSiblingResearch: retainedTurnDelta.followUp.siblingResearch.flatMap((handoff) => {
|
|
2777
|
+
const handoffSha256 = digest(handoff);
|
|
2778
|
+
if (previousSiblings?.get(handoff.toolName) !== handoffSha256) return [];
|
|
2779
|
+
return [
|
|
2780
|
+
{
|
|
2781
|
+
toolName: handoff.toolName,
|
|
2782
|
+
researchInputsSha256: handoff.researchInputsSha256,
|
|
2783
|
+
handoffSha256,
|
|
2784
|
+
handoffRef: memory.remember(handoff),
|
|
2785
|
+
},
|
|
2786
|
+
];
|
|
2787
|
+
}),
|
|
2788
|
+
}
|
|
2789
|
+
: undefined;
|
|
2674
2790
|
const retainedInput = retainedTurnDelta
|
|
2675
2791
|
? (({ kind, ...delta }) => ({
|
|
2676
2792
|
instruction:
|
|
2677
2793
|
kind === 'master_follow_up'
|
|
2678
|
-
? 'Continue the same retained API-research conversation. Follow this new master direction using the recording evidence already in this conversation. The evidenceRef identifies the current immutable projection; if a newly selected recorded request is needed, use inspect with its exact request seq to retrieve only that evidence. Test complete candidates until the named proof gap is resolved, remains partial with a better exact handoff, or is factually blocked.'
|
|
2794
|
+
? 'Continue the same retained API-research conversation. Follow this new master direction using the recording evidence already in this conversation. siblingResearch contains new or changed handoffs; retainedSiblingResearch identifies unchanged handoffs already delivered to you. Use their retained exact proof, or read handoffRef through shared research when present; a sibling test does not prove this tool. The evidenceRef identifies the current immutable projection; if a newly selected recorded request is needed, use inspect with its exact request seq to retrieve only that evidence. Test complete candidates until the named proof gap is resolved, remains partial with a better exact handoff, or is factually blocked.'
|
|
2679
2795
|
: kind === 'observation'
|
|
2680
2796
|
? 'Continue the same retained API-research conversation. Evaluate this newest factual test result. Return partial only when the selected core result or a required downstream obligation remains incomplete; defer optional breadth and further minimization.'
|
|
2681
2797
|
: kind === 'catalog_page'
|
|
@@ -2687,9 +2803,10 @@ export async function requestApiResearchStep(
|
|
|
2687
2803
|
: 'Review your proposed blocker once using the retained evidence. Return another evidence-backed action when one remains, otherwise return blocked with the exact factual reason.',
|
|
2688
2804
|
turnKind: kind,
|
|
2689
2805
|
...delta,
|
|
2806
|
+
...(followUp ? { followUp } : {}),
|
|
2690
2807
|
}))(retainedTurnDelta)
|
|
2691
2808
|
: undefined;
|
|
2692
|
-
|
|
2809
|
+
const output = await request({
|
|
2693
2810
|
role: 'API researcher',
|
|
2694
2811
|
conversationKey: `tool:${checked.tool.candidate.toolName}:api-researcher`,
|
|
2695
2812
|
prompt: 'master-teach-api-researcher.md',
|
|
@@ -2717,6 +2834,19 @@ export async function requestApiResearchStep(
|
|
|
2717
2834
|
schema: apiResearchOutputSchema(checked),
|
|
2718
2835
|
agent,
|
|
2719
2836
|
});
|
|
2837
|
+
if (
|
|
2838
|
+
retainedOwner &&
|
|
2839
|
+
checked.followUp &&
|
|
2840
|
+
(!retainedTurnDelta || retainedTurnDelta.kind === 'master_follow_up')
|
|
2841
|
+
) {
|
|
2842
|
+
const conversations = researchSiblingDelivery.get(retainedOwner) ?? new Map();
|
|
2843
|
+
const handoffs = new Map(previousSiblings);
|
|
2844
|
+
for (const handoff of checked.followUp.siblingResearch)
|
|
2845
|
+
handoffs.set(handoff.toolName, digest(handoff));
|
|
2846
|
+
conversations.set(conversation, { runId: checked.run.runId, handoffs });
|
|
2847
|
+
researchSiblingDelivery.set(retainedOwner, conversations);
|
|
2848
|
+
}
|
|
2849
|
+
return output;
|
|
2720
2850
|
}
|
|
2721
2851
|
// Only retain delivery fingerprints for an actual shared analyzer conversation.
|
|
2722
2852
|
// Full research history remains in the host input and the provider conversation.
|
|
@@ -2766,6 +2896,91 @@ export async function requestMasterDecision(
|
|
|
2766
2896
|
}
|
|
2767
2897
|
return output;
|
|
2768
2898
|
}
|
|
2899
|
+
const LiveComponentRecoveryInputSchema = z.object({
|
|
2900
|
+
toolName: z.string().min(1),
|
|
2901
|
+
toolId: z.string().optional(),
|
|
2902
|
+
phase: z.string().default('live'),
|
|
2903
|
+
authenticationAvailable: z.boolean(),
|
|
2904
|
+
components: z.array(
|
|
2905
|
+
z.object({
|
|
2906
|
+
id: z.string().min(1),
|
|
2907
|
+
kind: z.string().min(1),
|
|
2908
|
+
label: z.string(),
|
|
2909
|
+
toolIds: z.array(z.string()),
|
|
2910
|
+
}),
|
|
2911
|
+
),
|
|
2912
|
+
parameters: z.record(z.union([z.string(), z.number(), z.boolean()])),
|
|
2913
|
+
failure: z.object({
|
|
2914
|
+
error: z.string().min(1),
|
|
2915
|
+
status: z.number().optional(),
|
|
2916
|
+
message: z.string(),
|
|
2917
|
+
missing: z.unknown().optional(),
|
|
2918
|
+
requestStageFacts: z.unknown().optional(),
|
|
2919
|
+
}),
|
|
2920
|
+
previousRecoveries: z.number().int().nonnegative(),
|
|
2921
|
+
recordedAuthentication: z.object({
|
|
2922
|
+
credentialRequestSeqs: z.array(z.number().int().nonnegative()),
|
|
2923
|
+
authRequestSeqs: z.array(z.number().int().nonnegative()),
|
|
2924
|
+
credentialNames: z.array(z.string()),
|
|
2925
|
+
notes: z.string(),
|
|
2926
|
+
}),
|
|
2927
|
+
contexts: z.array(
|
|
2928
|
+
z.object({
|
|
2929
|
+
contextRef: z.string(),
|
|
2930
|
+
label: z.string(),
|
|
2931
|
+
workflowPath: z.string().optional(),
|
|
2932
|
+
latestAction: z.string().optional(),
|
|
2933
|
+
latestOk: z.boolean().optional(),
|
|
2934
|
+
latestStatus: z.number().optional(),
|
|
2935
|
+
latestError: z.string().optional(),
|
|
2936
|
+
}),
|
|
2937
|
+
),
|
|
2938
|
+
});
|
|
2939
|
+
export type LiveComponentRecoveryInput = z.input<typeof LiveComponentRecoveryInputSchema>;
|
|
2940
|
+
|
|
2941
|
+
export async function requestLiveComponentRecovery(
|
|
2942
|
+
input: LiveComponentRecoveryInput,
|
|
2943
|
+
agent: MasterTeachAgentOptions = {},
|
|
2944
|
+
) {
|
|
2945
|
+
const checked = LiveComponentRecoveryInputSchema.parse(input);
|
|
2946
|
+
return request({
|
|
2947
|
+
role: 'component recovery',
|
|
2948
|
+
conversationKey: `tool:${checked.toolName}:component-recovery`,
|
|
2949
|
+
prompt: 'component-recovery.md',
|
|
2950
|
+
input: checked,
|
|
2951
|
+
validation: { toolName: checked.toolName },
|
|
2952
|
+
schema: z
|
|
2953
|
+
.discriminatedUnion('action', [
|
|
2954
|
+
z
|
|
2955
|
+
.object({
|
|
2956
|
+
action: z.literal('authenticate'),
|
|
2957
|
+
plan: AgentInteractionSchema.options[1].shape.plan,
|
|
2958
|
+
reason: z.string().min(1),
|
|
2959
|
+
})
|
|
2960
|
+
.strict(),
|
|
2961
|
+
z
|
|
2962
|
+
.object({
|
|
2963
|
+
action: z.literal('recover_component'),
|
|
2964
|
+
componentId: z.string().min(1),
|
|
2965
|
+
reason: z.string().min(1),
|
|
2966
|
+
})
|
|
2967
|
+
.strict(),
|
|
2968
|
+
z.object({ action: z.literal('return_failure'), reason: z.string().min(1) }).strict(),
|
|
2969
|
+
])
|
|
2970
|
+
.superRefine((decision, ctx) => {
|
|
2971
|
+
if (decision.action === 'authenticate' && !checked.authenticationAvailable)
|
|
2972
|
+
issue(ctx, ['action'], 'No authentication owner is attached');
|
|
2973
|
+
if (
|
|
2974
|
+
decision.action === 'recover_component' &&
|
|
2975
|
+
!checked.components.some((c) => c.id === decision.componentId)
|
|
2976
|
+
)
|
|
2977
|
+
issue(ctx, ['componentId'], 'Choose an explicitly supplied component owner');
|
|
2978
|
+
}),
|
|
2979
|
+
agent,
|
|
2980
|
+
allowInteractions: false,
|
|
2981
|
+
});
|
|
2982
|
+
}
|
|
2983
|
+
|
|
2769
2984
|
export async function requestParameterSelectionAdvice(
|
|
2770
2985
|
input: ParameterSelectionAdvisorInput,
|
|
2771
2986
|
agent: MasterTeachAgentOptions = {},
|
|
@@ -328,7 +328,14 @@ export function invocationOutcomeCheck(input: {
|
|
|
328
328
|
);
|
|
329
329
|
} else {
|
|
330
330
|
facts.push(
|
|
331
|
-
ReceiptFactSchema.parse({
|
|
331
|
+
ReceiptFactSchema.parse({
|
|
332
|
+
...invocationBase,
|
|
333
|
+
status: 'failed',
|
|
334
|
+
errorCode: input.outcome.result.error,
|
|
335
|
+
...(input.outcome.result.status === undefined
|
|
336
|
+
? {}
|
|
337
|
+
: { httpStatus: input.outcome.result.status }),
|
|
338
|
+
}),
|
|
332
339
|
ReceiptFactSchema.parse({
|
|
333
340
|
kind: 'result',
|
|
334
341
|
subject: input.subject,
|