Deploy multi-file Hub workflows (#3128)
* feat(hub): deploy canonical workflow bundles Keep CLI deployment aligned with Hub's authored bundle boundary so validation and activation receive the same deterministic source files. Public documentation now teaches that boundary as the only configuration format. * test(hub): assert validation diagnostics directly * refactor(hub): deepen HTTP client module * feat(hub): validate named agent configurations * docs(hub): align Claude mode example
This commit is contained in:
@@ -66,6 +66,34 @@ const PreviousHubAgentCreateWithAutoArchiveRequestSchema =
|
||||
});
|
||||
|
||||
describe("Hub session protocol", () => {
|
||||
test("round-trips named-agent validation", () => {
|
||||
const request = {
|
||||
type: "hub.execution.agent.validate.request" as const,
|
||||
requestId: "validate-codex",
|
||||
provider: "codex",
|
||||
model: "gpt-5.5",
|
||||
thinkingOptionId: "xhigh",
|
||||
providerOptions: {
|
||||
sandbox_workspace_write: {
|
||||
writable_roots: ["/var/cache/npm"],
|
||||
network_access: false,
|
||||
},
|
||||
},
|
||||
};
|
||||
const response = {
|
||||
type: "hub.execution.agent.validate.response" as const,
|
||||
payload: {
|
||||
requestId: request.requestId,
|
||||
valid: true,
|
||||
issues: [],
|
||||
error: null,
|
||||
},
|
||||
};
|
||||
|
||||
expect(SessionInboundMessageSchema.parse(request)).toEqual(request);
|
||||
expect(SessionOutboundMessageSchema.parse(response)).toEqual(response);
|
||||
});
|
||||
|
||||
test("accepts the Hub execution create request", () => {
|
||||
const message = {
|
||||
type: "hub.execution.agent.create.request",
|
||||
|
||||
@@ -2530,6 +2530,20 @@ export const HubExecutionAgentCreateRequestSchema = z.object({
|
||||
|
||||
export type HubExecutionAgentCreateRequest = z.infer<typeof HubExecutionAgentCreateRequestSchema>;
|
||||
|
||||
export const HubExecutionAgentValidateRequestSchema = z.object({
|
||||
type: z.literal("hub.execution.agent.validate.request"),
|
||||
requestId: z.string(),
|
||||
provider: z.string(),
|
||||
model: z.string().optional(),
|
||||
modeId: z.string().optional(),
|
||||
thinkingOptionId: z.string().optional(),
|
||||
providerOptions: ProviderOptionsSchema.optional(),
|
||||
});
|
||||
|
||||
export type HubExecutionAgentValidateRequest = z.infer<
|
||||
typeof HubExecutionAgentValidateRequestSchema
|
||||
>;
|
||||
|
||||
const HubExecutionAgentCreateErrorSchema = z.discriminatedUnion("code", [
|
||||
z.object({
|
||||
code: z.literal("provider_options_invalid"),
|
||||
@@ -2569,6 +2583,7 @@ export type HubExecutionControlRequest = z.infer<typeof HubExecutionControlReque
|
||||
|
||||
export const SessionInboundMessageSchema = z.discriminatedUnion("type", [
|
||||
HubExecutionAgentCreateRequestSchema,
|
||||
HubExecutionAgentValidateRequestSchema,
|
||||
HubExecutionControlRequestSchema,
|
||||
BrowserAutomationExecuteResponseSchema,
|
||||
VoiceAudioChunkMessageSchema,
|
||||
@@ -5340,6 +5355,25 @@ export const HubExecutionAgentCreateResponseSchema = z.object({
|
||||
}),
|
||||
});
|
||||
|
||||
export const HubExecutionAgentValidationIssueSchema = z.object({
|
||||
path: z.array(z.union([z.string(), z.number()])),
|
||||
message: z.string(),
|
||||
});
|
||||
|
||||
export type HubExecutionAgentValidationIssue = z.infer<
|
||||
typeof HubExecutionAgentValidationIssueSchema
|
||||
>;
|
||||
|
||||
export const HubExecutionAgentValidateResponseSchema = z.object({
|
||||
type: z.literal("hub.execution.agent.validate.response"),
|
||||
payload: z.object({
|
||||
requestId: z.string(),
|
||||
valid: z.boolean(),
|
||||
issues: z.array(HubExecutionAgentValidationIssueSchema),
|
||||
error: z.string().nullable(),
|
||||
}),
|
||||
});
|
||||
|
||||
export const HubExecutionControlResponseSchema = z.object({
|
||||
type: z.literal("hub.execution.control.response"),
|
||||
payload: z.object({
|
||||
@@ -5370,12 +5404,16 @@ export const HubExecutionAgentStreamSchema = z.object({
|
||||
});
|
||||
|
||||
export type HubExecutionAgentCreateResponse = z.infer<typeof HubExecutionAgentCreateResponseSchema>;
|
||||
export type HubExecutionAgentValidateResponse = z.infer<
|
||||
typeof HubExecutionAgentValidateResponseSchema
|
||||
>;
|
||||
export type HubExecutionControlResponse = z.infer<typeof HubExecutionControlResponseSchema>;
|
||||
export type HubExecutionAgentUpdate = z.infer<typeof HubExecutionAgentUpdateSchema>;
|
||||
export type HubExecutionAgentStream = z.infer<typeof HubExecutionAgentStreamSchema>;
|
||||
|
||||
export const HubExecutionOutboundMessageSchema = z.discriminatedUnion("type", [
|
||||
HubExecutionAgentCreateResponseSchema,
|
||||
HubExecutionAgentValidateResponseSchema,
|
||||
HubExecutionControlResponseSchema,
|
||||
HubExecutionAgentUpdateSchema,
|
||||
HubExecutionAgentStreamSchema,
|
||||
@@ -5409,6 +5447,7 @@ export type DaemonUpdateProgressMessage = z.infer<typeof DaemonUpdateProgressMes
|
||||
|
||||
export const SessionOutboundMessageSchema = z.discriminatedUnion("type", [
|
||||
HubExecutionAgentCreateResponseSchema,
|
||||
HubExecutionAgentValidateResponseSchema,
|
||||
HubExecutionControlResponseSchema,
|
||||
HubExecutionAgentUpdateSchema,
|
||||
HubExecutionAgentStreamSchema,
|
||||
|
||||
Reference in New Issue
Block a user