@shipfox/api-agent-access-dto 21.0.0 → 21.1.0
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/.turbo/turbo-build.log +1 -1
- package/.turbo/turbo-type.log +0 -1
- package/CHANGELOG.md +8 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/schemas/diagnostic-tools.d.ts.map +1 -1
- package/dist/schemas/diagnostic-tools.js +1 -6
- package/dist/schemas/diagnostic-tools.js.map +1 -1
- package/dist/schemas/log-tools.d.ts +215 -0
- package/dist/schemas/log-tools.d.ts.map +1 -0
- package/dist/schemas/log-tools.js +224 -0
- package/dist/schemas/log-tools.js.map +1 -0
- package/dist/schemas/paged-tools.d.ts.map +1 -1
- package/dist/schemas/paged-tools.js +1 -6
- package/dist/schemas/paged-tools.js.map +1 -1
- package/dist/schemas/primitives.d.ts +5 -0
- package/dist/schemas/primitives.d.ts.map +1 -0
- package/dist/schemas/primitives.js +9 -0
- package/dist/schemas/primitives.js.map +1 -0
- package/dist/schemas/workflow-diagnostics.d.ts +862 -0
- package/dist/schemas/workflow-diagnostics.d.ts.map +1 -0
- package/dist/schemas/workflow-diagnostics.js +876 -0
- package/dist/schemas/workflow-diagnostics.js.map +1 -0
- package/dist/schemas/workflow-tools.d.ts +1305 -0
- package/dist/schemas/workflow-tools.d.ts.map +1 -0
- package/dist/schemas/workflow-tools.js +938 -0
- package/dist/schemas/workflow-tools.js.map +1 -0
- package/dist/tsconfig.test.tsbuildinfo +1 -1
- package/package.json +3 -2
- package/src/index.ts +96 -0
- package/src/schemas/diagnostic-tools.ts +1 -12
- package/src/schemas/log-tools.ts +209 -0
- package/src/schemas/paged-tools.ts +1 -10
- package/src/schemas/primitives.ts +14 -0
- package/src/schemas/workflow-diagnostics.test.ts +277 -0
- package/src/schemas/workflow-diagnostics.ts +693 -0
- package/src/schemas/workflow-tools.test.ts +202 -0
- package/src/schemas/workflow-tools.ts +738 -0
- package/tsconfig.build.tsbuildinfo +1 -1
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shipfox/api-agent-access-dto",
|
|
3
3
|
"license": "MIT",
|
|
4
|
-
"version": "21.
|
|
4
|
+
"version": "21.1.0",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
7
7
|
"url": "git+https://github.com/ShipfoxHQ/shipfox.git",
|
|
@@ -31,7 +31,8 @@
|
|
|
31
31
|
}
|
|
32
32
|
},
|
|
33
33
|
"dependencies": {
|
|
34
|
-
"zod": "^4.4.3"
|
|
34
|
+
"zod": "^4.4.3",
|
|
35
|
+
"@shipfox/api-logs-dto": "20.0.0"
|
|
35
36
|
},
|
|
36
37
|
"devDependencies": {
|
|
37
38
|
"@shipfox/biome": "1.10.1",
|
package/src/index.ts
CHANGED
|
@@ -29,6 +29,19 @@ export {
|
|
|
29
29
|
agentAccessErrorSchema,
|
|
30
30
|
agentAccessOutputSchema,
|
|
31
31
|
} from './schemas/envelope.js';
|
|
32
|
+
export {
|
|
33
|
+
AGENT_ACCESS_LOG_ATTEMPT_MAX,
|
|
34
|
+
AGENT_ACCESS_LOG_CONTENT_MAX_BYTES,
|
|
35
|
+
AGENT_ACCESS_LOG_SECTION_MAX_ITEMS,
|
|
36
|
+
AGENT_ACCESS_LOG_TAIL_LINES_DEFAULT,
|
|
37
|
+
AGENT_ACCESS_LOG_TAIL_LINES_MAX,
|
|
38
|
+
type GetStepLogsInputDto,
|
|
39
|
+
type GetStepLogsResultDto,
|
|
40
|
+
getStepLogsInputJsonSchema,
|
|
41
|
+
getStepLogsInputSchema,
|
|
42
|
+
getStepLogsResultJsonSchema,
|
|
43
|
+
getStepLogsResultSchema,
|
|
44
|
+
} from './schemas/log-tools.js';
|
|
32
45
|
export {
|
|
33
46
|
AGENT_ACCESS_ANNOTATION_BODY_MAX_BYTES,
|
|
34
47
|
AGENT_ACCESS_CONNECTION_NAME_MAX_BYTES,
|
|
@@ -71,3 +84,86 @@ export {
|
|
|
71
84
|
listWorkflowRunsResultJsonSchema,
|
|
72
85
|
listWorkflowRunsResultSchema,
|
|
73
86
|
} from './schemas/paged-tools.js';
|
|
87
|
+
export {
|
|
88
|
+
AGENT_ACCESS_WORKFLOW_DIAGNOSTIC_VALUE_MAX_BYTES,
|
|
89
|
+
AGENT_ACCESS_WORKFLOW_SOURCE_MAX_BYTES,
|
|
90
|
+
type AgentAccessOversizedFieldDto,
|
|
91
|
+
type AgentAccessWorkflowDiagnosticFieldDto,
|
|
92
|
+
agentAccessOversizedFieldSchema,
|
|
93
|
+
agentAccessWorkflowDiagnosticFieldSchema,
|
|
94
|
+
type GetStepAttemptInputDto,
|
|
95
|
+
type GetStepAttemptResultDto,
|
|
96
|
+
type GetWorkflowExecutionContextInputDto,
|
|
97
|
+
type GetWorkflowExecutionContextResultDto,
|
|
98
|
+
type GetWorkflowRunSourceInputDto,
|
|
99
|
+
type GetWorkflowRunSourceResultDto,
|
|
100
|
+
getStepAttemptInputJsonSchema,
|
|
101
|
+
getStepAttemptInputSchema,
|
|
102
|
+
getStepAttemptResultJsonSchema,
|
|
103
|
+
getStepAttemptResultSchema,
|
|
104
|
+
getWorkflowExecutionContextInputJsonSchema,
|
|
105
|
+
getWorkflowExecutionContextInputSchema,
|
|
106
|
+
getWorkflowExecutionContextResultJsonSchema,
|
|
107
|
+
getWorkflowExecutionContextResultSchema,
|
|
108
|
+
getWorkflowRunSourceInputJsonSchema,
|
|
109
|
+
getWorkflowRunSourceInputSchema,
|
|
110
|
+
getWorkflowRunSourceResultJsonSchema,
|
|
111
|
+
getWorkflowRunSourceResultSchema,
|
|
112
|
+
type ListWorkflowRunJobExplanationsInputDto,
|
|
113
|
+
type ListWorkflowRunJobExplanationsResultDto,
|
|
114
|
+
listWorkflowRunJobExplanationsInputJsonSchema,
|
|
115
|
+
listWorkflowRunJobExplanationsInputSchema,
|
|
116
|
+
listWorkflowRunJobExplanationsResultJsonSchema,
|
|
117
|
+
listWorkflowRunJobExplanationsResultSchema,
|
|
118
|
+
} from './schemas/workflow-diagnostics.js';
|
|
119
|
+
export {
|
|
120
|
+
AGENT_ACCESS_WORKFLOW_ATTEMPT_MAX,
|
|
121
|
+
AGENT_ACCESS_WORKFLOW_EXECUTION_COUNT_MAX,
|
|
122
|
+
AGENT_ACCESS_WORKFLOW_EXECUTION_PAGE_LIMIT,
|
|
123
|
+
AGENT_ACCESS_WORKFLOW_JOB_PAGE_LIMIT,
|
|
124
|
+
AGENT_ACCESS_WORKFLOW_RUN_ATTEMPT_PAGE_LIMIT,
|
|
125
|
+
AGENT_ACCESS_WORKFLOW_STEP_ATTEMPT_PAGE_LIMIT,
|
|
126
|
+
AGENT_ACCESS_WORKFLOW_STEP_PAGE_LIMIT,
|
|
127
|
+
type GetWorkflowJobInputDto,
|
|
128
|
+
type GetWorkflowJobResultDto,
|
|
129
|
+
type GetWorkflowRunInputDto,
|
|
130
|
+
type GetWorkflowRunResultDto,
|
|
131
|
+
getWorkflowJobInputJsonSchema,
|
|
132
|
+
getWorkflowJobInputSchema,
|
|
133
|
+
getWorkflowJobResultJsonSchema,
|
|
134
|
+
getWorkflowJobResultSchema,
|
|
135
|
+
getWorkflowRunInputJsonSchema,
|
|
136
|
+
getWorkflowRunInputSchema,
|
|
137
|
+
getWorkflowRunResultJsonSchema,
|
|
138
|
+
getWorkflowRunResultSchema,
|
|
139
|
+
type ListWorkflowExecutionStepsInputDto,
|
|
140
|
+
type ListWorkflowExecutionStepsResultDto,
|
|
141
|
+
type ListWorkflowJobExecutionsInputDto,
|
|
142
|
+
type ListWorkflowJobExecutionsResultDto,
|
|
143
|
+
type ListWorkflowRunAttemptsInputDto,
|
|
144
|
+
type ListWorkflowRunAttemptsResultDto,
|
|
145
|
+
type ListWorkflowRunJobsInputDto,
|
|
146
|
+
type ListWorkflowRunJobsResultDto,
|
|
147
|
+
type ListWorkflowStepAttemptsInputDto,
|
|
148
|
+
type ListWorkflowStepAttemptsResultDto,
|
|
149
|
+
listWorkflowExecutionStepsInputJsonSchema,
|
|
150
|
+
listWorkflowExecutionStepsInputSchema,
|
|
151
|
+
listWorkflowExecutionStepsResultJsonSchema,
|
|
152
|
+
listWorkflowExecutionStepsResultSchema,
|
|
153
|
+
listWorkflowJobExecutionsInputJsonSchema,
|
|
154
|
+
listWorkflowJobExecutionsInputSchema,
|
|
155
|
+
listWorkflowJobExecutionsResultJsonSchema,
|
|
156
|
+
listWorkflowJobExecutionsResultSchema,
|
|
157
|
+
listWorkflowRunAttemptsInputJsonSchema,
|
|
158
|
+
listWorkflowRunAttemptsInputSchema,
|
|
159
|
+
listWorkflowRunAttemptsResultJsonSchema,
|
|
160
|
+
listWorkflowRunAttemptsResultSchema,
|
|
161
|
+
listWorkflowRunJobsInputJsonSchema,
|
|
162
|
+
listWorkflowRunJobsInputSchema,
|
|
163
|
+
listWorkflowRunJobsResultJsonSchema,
|
|
164
|
+
listWorkflowRunJobsResultSchema,
|
|
165
|
+
listWorkflowStepAttemptsInputJsonSchema,
|
|
166
|
+
listWorkflowStepAttemptsInputSchema,
|
|
167
|
+
listWorkflowStepAttemptsResultJsonSchema,
|
|
168
|
+
listWorkflowStepAttemptsResultSchema,
|
|
169
|
+
} from './schemas/workflow-tools.js';
|
|
@@ -4,6 +4,7 @@ import {
|
|
|
4
4
|
AGENT_ACCESS_CONNECTION_NAME_MAX_BYTES,
|
|
5
5
|
AGENT_ACCESS_TEXT_MAX_BYTES,
|
|
6
6
|
} from './paged-tools.js';
|
|
7
|
+
import {dateTimeSchema, idSchema, utf8CappedString} from './primitives.js';
|
|
7
8
|
|
|
8
9
|
export const AGENT_ACCESS_SERIALIZED_JSON_MAX_BYTES = 16 * 1024;
|
|
9
10
|
export const AGENT_ACCESS_TRIGGER_DECISION_MAX_ITEMS = 50;
|
|
@@ -11,18 +12,6 @@ export const AGENT_ACCESS_TRIGGER_REPLAY_MAX_ITEMS = 20;
|
|
|
11
12
|
export const AGENT_ACCESS_FACET_MAX_ITEMS = 50;
|
|
12
13
|
export const AGENT_ACCESS_FACET_VALUE_MAX_BYTES = 256;
|
|
13
14
|
|
|
14
|
-
const idSchema = z.string().uuid();
|
|
15
|
-
const dateTimeSchema = z.string().datetime();
|
|
16
|
-
const utf8Encoder = new TextEncoder();
|
|
17
|
-
|
|
18
|
-
const utf8CappedString = (maxBytes: number) =>
|
|
19
|
-
z
|
|
20
|
-
.string()
|
|
21
|
-
.max(maxBytes)
|
|
22
|
-
.refine((value) => utf8Encoder.encode(value).byteLength <= maxBytes, {
|
|
23
|
-
message: `String must contain at most ${maxBytes} UTF-8 bytes`,
|
|
24
|
-
});
|
|
25
|
-
|
|
26
15
|
const textSchema = utf8CappedString(AGENT_ACCESS_TEXT_MAX_BYTES);
|
|
27
16
|
const shortTextSchema = utf8CappedString(AGENT_ACCESS_CONNECTION_NAME_MAX_BYTES);
|
|
28
17
|
const serializedJsonSchema = utf8CappedString(AGENT_ACCESS_SERIALIZED_JSON_MAX_BYTES).refine(
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
import {
|
|
2
|
+
DEFAULT_STEP_LOG_TAIL_LINES,
|
|
3
|
+
MAX_STEP_LOG_TAIL_LINES,
|
|
4
|
+
} from '@shipfox/api-logs-dto/inter-module';
|
|
5
|
+
import {z} from 'zod';
|
|
6
|
+
import type {AgentAccessObjectSchema} from './envelope.js';
|
|
7
|
+
import {idSchema, utf8CappedString} from './primitives.js';
|
|
8
|
+
|
|
9
|
+
export const AGENT_ACCESS_LOG_CONTENT_MAX_BYTES = 64 * 1024;
|
|
10
|
+
export const AGENT_ACCESS_LOG_SECTION_MAX_ITEMS = 10;
|
|
11
|
+
export const AGENT_ACCESS_LOG_TAIL_LINES_DEFAULT = DEFAULT_STEP_LOG_TAIL_LINES;
|
|
12
|
+
export const AGENT_ACCESS_LOG_TAIL_LINES_MAX = MAX_STEP_LOG_TAIL_LINES;
|
|
13
|
+
export const AGENT_ACCESS_LOG_ATTEMPT_MAX = 2_147_483_647;
|
|
14
|
+
|
|
15
|
+
const attemptSchema = z.number().int().min(1).max(AGENT_ACCESS_LOG_ATTEMPT_MAX);
|
|
16
|
+
const tailLinesSchema = z
|
|
17
|
+
.number()
|
|
18
|
+
.int()
|
|
19
|
+
.min(1)
|
|
20
|
+
.max(AGENT_ACCESS_LOG_TAIL_LINES_MAX)
|
|
21
|
+
.default(AGENT_ACCESS_LOG_TAIL_LINES_DEFAULT);
|
|
22
|
+
const contentSchema = utf8CappedString(AGENT_ACCESS_LOG_CONTENT_MAX_BYTES);
|
|
23
|
+
|
|
24
|
+
export const getStepLogsInputSchema = z
|
|
25
|
+
.object({
|
|
26
|
+
step_id: idSchema.optional(),
|
|
27
|
+
run_id: idSchema.optional(),
|
|
28
|
+
attempt: attemptSchema.optional(),
|
|
29
|
+
failed_only: z.literal(true).optional(),
|
|
30
|
+
tail_lines: tailLinesSchema,
|
|
31
|
+
})
|
|
32
|
+
.superRefine((value, context) => {
|
|
33
|
+
const hasStep = value.step_id !== undefined;
|
|
34
|
+
const hasRun = value.run_id !== undefined;
|
|
35
|
+
|
|
36
|
+
if (hasStep === hasRun) {
|
|
37
|
+
context.addIssue({
|
|
38
|
+
code: 'custom',
|
|
39
|
+
path: [hasStep ? 'run_id' : 'step_id'],
|
|
40
|
+
message: 'Provide exactly one of step_id or run_id',
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
if (hasRun && value.failed_only !== true) {
|
|
44
|
+
context.addIssue({
|
|
45
|
+
code: 'custom',
|
|
46
|
+
path: ['failed_only'],
|
|
47
|
+
message: 'run_id requires failed_only to be true',
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
if (hasStep && value.failed_only !== undefined) {
|
|
51
|
+
context.addIssue({
|
|
52
|
+
code: 'custom',
|
|
53
|
+
path: ['failed_only'],
|
|
54
|
+
message: 'failed_only is only valid with run_id',
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
if (hasRun && value.attempt !== undefined) {
|
|
58
|
+
context.addIssue({
|
|
59
|
+
code: 'custom',
|
|
60
|
+
path: ['attempt'],
|
|
61
|
+
message: 'attempt is only valid with step_id',
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
})
|
|
65
|
+
.strict();
|
|
66
|
+
|
|
67
|
+
export type GetStepLogsInputDto = z.output<typeof getStepLogsInputSchema>;
|
|
68
|
+
|
|
69
|
+
const logSectionSchema = z
|
|
70
|
+
.object({
|
|
71
|
+
workflow_run_id: idSchema.optional(),
|
|
72
|
+
workflow_run_attempt: attemptSchema.optional(),
|
|
73
|
+
job_id: idSchema.optional(),
|
|
74
|
+
job_execution_id: idSchema.optional(),
|
|
75
|
+
step_id: idSchema,
|
|
76
|
+
step_attempt_id: idSchema.optional(),
|
|
77
|
+
attempt: attemptSchema,
|
|
78
|
+
content: contentSchema,
|
|
79
|
+
total_lines: z.number().int().nonnegative().optional(),
|
|
80
|
+
content_truncated: z.literal(true).optional(),
|
|
81
|
+
content_total_bytes: z.number().int().nonnegative().optional(),
|
|
82
|
+
})
|
|
83
|
+
.strict();
|
|
84
|
+
|
|
85
|
+
export const getStepLogsResultSchema = z
|
|
86
|
+
.object({
|
|
87
|
+
run_id: idSchema.optional(),
|
|
88
|
+
workflow_run_attempt: attemptSchema.optional(),
|
|
89
|
+
sections: z.array(logSectionSchema).max(AGENT_ACCESS_LOG_SECTION_MAX_ITEMS),
|
|
90
|
+
})
|
|
91
|
+
.superRefine((value, context) => {
|
|
92
|
+
const hasRun = value.run_id !== undefined;
|
|
93
|
+
const hasRunAttempt = value.workflow_run_attempt !== undefined;
|
|
94
|
+
|
|
95
|
+
if (hasRun !== hasRunAttempt) {
|
|
96
|
+
context.addIssue({
|
|
97
|
+
code: 'custom',
|
|
98
|
+
path: [hasRun ? 'workflow_run_attempt' : 'run_id'],
|
|
99
|
+
message: 'run_id and workflow_run_attempt must be provided together',
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
if (!hasRun && value.sections.length !== 1) {
|
|
103
|
+
context.addIssue({
|
|
104
|
+
code: 'custom',
|
|
105
|
+
path: ['sections'],
|
|
106
|
+
message: 'A direct step read must contain exactly one section',
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
})
|
|
110
|
+
.strict();
|
|
111
|
+
|
|
112
|
+
export type GetStepLogsResultDto = z.output<typeof getStepLogsResultSchema>;
|
|
113
|
+
|
|
114
|
+
const uuid = {type: 'string', format: 'uuid'} as const;
|
|
115
|
+
const attempt = {
|
|
116
|
+
type: 'integer',
|
|
117
|
+
minimum: 1,
|
|
118
|
+
maximum: AGENT_ACCESS_LOG_ATTEMPT_MAX,
|
|
119
|
+
} as const;
|
|
120
|
+
|
|
121
|
+
const directInputJsonSchema = {
|
|
122
|
+
type: 'object',
|
|
123
|
+
properties: {
|
|
124
|
+
step_id: uuid,
|
|
125
|
+
attempt,
|
|
126
|
+
tail_lines: {
|
|
127
|
+
type: 'integer',
|
|
128
|
+
minimum: 1,
|
|
129
|
+
maximum: AGENT_ACCESS_LOG_TAIL_LINES_MAX,
|
|
130
|
+
default: AGENT_ACCESS_LOG_TAIL_LINES_DEFAULT,
|
|
131
|
+
},
|
|
132
|
+
},
|
|
133
|
+
required: ['step_id'],
|
|
134
|
+
additionalProperties: false,
|
|
135
|
+
} as const;
|
|
136
|
+
|
|
137
|
+
const failedOnlyInputJsonSchema = {
|
|
138
|
+
type: 'object',
|
|
139
|
+
properties: {
|
|
140
|
+
run_id: uuid,
|
|
141
|
+
failed_only: {const: true},
|
|
142
|
+
tail_lines: {
|
|
143
|
+
type: 'integer',
|
|
144
|
+
minimum: 1,
|
|
145
|
+
maximum: AGENT_ACCESS_LOG_TAIL_LINES_MAX,
|
|
146
|
+
default: AGENT_ACCESS_LOG_TAIL_LINES_DEFAULT,
|
|
147
|
+
},
|
|
148
|
+
},
|
|
149
|
+
required: ['run_id', 'failed_only'],
|
|
150
|
+
additionalProperties: false,
|
|
151
|
+
} as const;
|
|
152
|
+
|
|
153
|
+
export const getStepLogsInputJsonSchema = {
|
|
154
|
+
type: 'object',
|
|
155
|
+
oneOf: [directInputJsonSchema, failedOnlyInputJsonSchema],
|
|
156
|
+
} as const satisfies AgentAccessObjectSchema;
|
|
157
|
+
|
|
158
|
+
const logSectionJsonSchema = {
|
|
159
|
+
type: 'object',
|
|
160
|
+
properties: {
|
|
161
|
+
workflow_run_id: uuid,
|
|
162
|
+
workflow_run_attempt: attempt,
|
|
163
|
+
job_id: uuid,
|
|
164
|
+
job_execution_id: uuid,
|
|
165
|
+
step_id: uuid,
|
|
166
|
+
step_attempt_id: uuid,
|
|
167
|
+
attempt,
|
|
168
|
+
content: {type: 'string', maxLength: AGENT_ACCESS_LOG_CONTENT_MAX_BYTES},
|
|
169
|
+
total_lines: {type: 'integer', minimum: 0},
|
|
170
|
+
content_truncated: {const: true},
|
|
171
|
+
content_total_bytes: {type: 'integer', minimum: 0},
|
|
172
|
+
},
|
|
173
|
+
required: ['step_id', 'attempt', 'content'],
|
|
174
|
+
additionalProperties: false,
|
|
175
|
+
} as const;
|
|
176
|
+
|
|
177
|
+
const directResultJsonSchema = {
|
|
178
|
+
type: 'object',
|
|
179
|
+
properties: {
|
|
180
|
+
sections: {
|
|
181
|
+
type: 'array',
|
|
182
|
+
minItems: 1,
|
|
183
|
+
maxItems: 1,
|
|
184
|
+
items: logSectionJsonSchema,
|
|
185
|
+
},
|
|
186
|
+
},
|
|
187
|
+
required: ['sections'],
|
|
188
|
+
additionalProperties: false,
|
|
189
|
+
} as const;
|
|
190
|
+
|
|
191
|
+
const aggregateResultJsonSchema = {
|
|
192
|
+
type: 'object',
|
|
193
|
+
properties: {
|
|
194
|
+
run_id: uuid,
|
|
195
|
+
workflow_run_attempt: attempt,
|
|
196
|
+
sections: {
|
|
197
|
+
type: 'array',
|
|
198
|
+
maxItems: AGENT_ACCESS_LOG_SECTION_MAX_ITEMS,
|
|
199
|
+
items: logSectionJsonSchema,
|
|
200
|
+
},
|
|
201
|
+
},
|
|
202
|
+
required: ['run_id', 'workflow_run_attempt', 'sections'],
|
|
203
|
+
additionalProperties: false,
|
|
204
|
+
} as const;
|
|
205
|
+
|
|
206
|
+
export const getStepLogsResultJsonSchema = {
|
|
207
|
+
type: 'object',
|
|
208
|
+
oneOf: [directResultJsonSchema, aggregateResultJsonSchema],
|
|
209
|
+
} as const satisfies AgentAccessObjectSchema;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import {z} from 'zod';
|
|
2
2
|
import type {AgentAccessObjectSchema} from './envelope.js';
|
|
3
|
+
import {dateTimeSchema, idSchema, utf8CappedString} from './primitives.js';
|
|
3
4
|
|
|
4
5
|
export const AGENT_ACCESS_DEFAULT_PAGE_LIMIT = 50;
|
|
5
6
|
export const AGENT_ACCESS_PAGE_LIMIT_MAX = 100;
|
|
@@ -12,16 +13,6 @@ export const AGENT_ACCESS_DIAGNOSTIC_PATH_MAX_BYTES = 512;
|
|
|
12
13
|
export const AGENT_ACCESS_DIAGNOSTIC_MAX_ITEMS = 10;
|
|
13
14
|
export const AGENT_ACCESS_ANNOTATION_BODY_MAX_BYTES = 8 * 1024;
|
|
14
15
|
|
|
15
|
-
const idSchema = z.string().uuid();
|
|
16
|
-
const dateTimeSchema = z.string().datetime();
|
|
17
|
-
const utf8Encoder = new TextEncoder();
|
|
18
|
-
const utf8CappedString = (maxBytes: number) =>
|
|
19
|
-
z
|
|
20
|
-
.string()
|
|
21
|
-
.max(maxBytes)
|
|
22
|
-
.refine((value) => utf8Encoder.encode(value).byteLength <= maxBytes, {
|
|
23
|
-
message: `String must contain at most ${maxBytes} UTF-8 bytes`,
|
|
24
|
-
});
|
|
25
16
|
const pageInputFields = {
|
|
26
17
|
limit: z
|
|
27
18
|
.number()
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import {z} from 'zod';
|
|
2
|
+
|
|
3
|
+
export const idSchema = z.string().uuid();
|
|
4
|
+
export const dateTimeSchema = z.string().datetime();
|
|
5
|
+
|
|
6
|
+
const utf8Encoder = new TextEncoder();
|
|
7
|
+
|
|
8
|
+
export const utf8CappedString = (maxBytes: number) =>
|
|
9
|
+
z
|
|
10
|
+
.string()
|
|
11
|
+
.max(maxBytes)
|
|
12
|
+
.refine((value) => utf8Encoder.encode(value).byteLength <= maxBytes, {
|
|
13
|
+
message: `String must contain at most ${maxBytes} UTF-8 bytes`,
|
|
14
|
+
});
|
|
@@ -0,0 +1,277 @@
|
|
|
1
|
+
import {agentAccessOutputSchema} from './envelope.js';
|
|
2
|
+
import {AGENT_ACCESS_PAGE_LIMIT_MAX} from './paged-tools.js';
|
|
3
|
+
import {
|
|
4
|
+
AGENT_ACCESS_WORKFLOW_SOURCE_MAX_BYTES,
|
|
5
|
+
getStepAttemptResultJsonSchema,
|
|
6
|
+
getStepAttemptResultSchema,
|
|
7
|
+
getWorkflowExecutionContextResultJsonSchema,
|
|
8
|
+
getWorkflowExecutionContextResultSchema,
|
|
9
|
+
getWorkflowRunSourceResultJsonSchema,
|
|
10
|
+
getWorkflowRunSourceResultSchema,
|
|
11
|
+
listWorkflowRunJobExplanationsResultJsonSchema,
|
|
12
|
+
listWorkflowRunJobExplanationsResultSchema,
|
|
13
|
+
} from './workflow-diagnostics.js';
|
|
14
|
+
import {AGENT_ACCESS_WORKFLOW_ATTEMPT_MAX} from './workflow-tools.js';
|
|
15
|
+
|
|
16
|
+
const runId = '00000000-0000-4000-8000-000000000001';
|
|
17
|
+
const jobId = '00000000-0000-4000-8000-000000000002';
|
|
18
|
+
const executionId = '00000000-0000-4000-8000-000000000003';
|
|
19
|
+
const stepId = '00000000-0000-4000-8000-000000000004';
|
|
20
|
+
const stepAttemptId = '00000000-0000-4000-8000-000000000005';
|
|
21
|
+
const projectId = '00000000-0000-4000-8000-000000000006';
|
|
22
|
+
const deliveryId = '00000000-0000-4000-8000-000000000007';
|
|
23
|
+
const isoDate = '2026-08-01T00:00:00.000Z';
|
|
24
|
+
|
|
25
|
+
describe('workflow diagnostic Agent Access schemas', () => {
|
|
26
|
+
test('accepts canonical source, context, step, and explanation values', () => {
|
|
27
|
+
expect(getWorkflowRunSourceResultSchema.safeParse(sourceAvailable()).success).toBe(true);
|
|
28
|
+
expect(getWorkflowRunSourceResultSchema.safeParse(sourceUnavailable()).success).toBe(true);
|
|
29
|
+
expect(getWorkflowExecutionContextResultSchema.safeParse(contextResult()).success).toBe(true);
|
|
30
|
+
expect(getStepAttemptResultSchema.safeParse(stepResult()).success).toBe(true);
|
|
31
|
+
expect(listWorkflowRunJobExplanationsResultSchema.safeParse(explanationsResult()).success).toBe(
|
|
32
|
+
true,
|
|
33
|
+
);
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
test('keeps source availability branches distinct in the JSON schema mirror', () => {
|
|
37
|
+
const branches = getWorkflowRunSourceResultJsonSchema.oneOf;
|
|
38
|
+
expect(branches).toHaveLength(2);
|
|
39
|
+
expect(branches[0]).toMatchObject({
|
|
40
|
+
properties: {kind: {const: 'available'}},
|
|
41
|
+
required: expect.arrayContaining(['source_snapshot']),
|
|
42
|
+
});
|
|
43
|
+
expect(branches[1]).toMatchObject({
|
|
44
|
+
properties: {kind: {const: 'unavailable'}},
|
|
45
|
+
required: expect.arrayContaining(['reason']),
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
expect(
|
|
49
|
+
getWorkflowRunSourceResultSchema.safeParse({
|
|
50
|
+
...sourceAvailable(),
|
|
51
|
+
reason: 'temporary_run',
|
|
52
|
+
}).success,
|
|
53
|
+
).toBe(false);
|
|
54
|
+
expect(
|
|
55
|
+
getWorkflowRunSourceResultSchema.safeParse({
|
|
56
|
+
...sourceUnavailable(),
|
|
57
|
+
source_snapshot: {content: 'name: build', format: 'yaml'},
|
|
58
|
+
}).success,
|
|
59
|
+
).toBe(false);
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
test('mirrors collection, truncation, and response-field bounds in tool schemas', () => {
|
|
63
|
+
const envelopes = [
|
|
64
|
+
agentAccessOutputSchema(getWorkflowRunSourceResultJsonSchema),
|
|
65
|
+
agentAccessOutputSchema(getWorkflowExecutionContextResultJsonSchema),
|
|
66
|
+
agentAccessOutputSchema(getStepAttemptResultJsonSchema),
|
|
67
|
+
agentAccessOutputSchema(listWorkflowRunJobExplanationsResultJsonSchema),
|
|
68
|
+
];
|
|
69
|
+
for (const envelope of envelopes) {
|
|
70
|
+
expect(envelope.type).toBe('object');
|
|
71
|
+
expect(envelope).not.toHaveProperty('oneOf');
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
expect(getWorkflowRunSourceResultJsonSchema.properties.workflow_run_attempt).toMatchObject({
|
|
75
|
+
maximum: AGENT_ACCESS_WORKFLOW_ATTEMPT_MAX,
|
|
76
|
+
});
|
|
77
|
+
expect(getWorkflowRunSourceResultJsonSchema.properties.source_snapshot).toMatchObject({
|
|
78
|
+
properties: {content: {maxLength: AGENT_ACCESS_WORKFLOW_SOURCE_MAX_BYTES}},
|
|
79
|
+
});
|
|
80
|
+
expect(getWorkflowRunSourceResultJsonSchema.properties.reason).toMatchObject({
|
|
81
|
+
enum: ['temporary_run', 'pre_snapshot_run', 'legacy_snapshot_too_large'],
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
expect(getStepAttemptResultJsonSchema.properties.error.anyOf[0]).toMatchObject({
|
|
85
|
+
properties: {
|
|
86
|
+
reason: {
|
|
87
|
+
enum: [
|
|
88
|
+
'checkout_failed',
|
|
89
|
+
'checkout_auth_failed',
|
|
90
|
+
'checkout_unavailable',
|
|
91
|
+
'checkout_path_invalid',
|
|
92
|
+
'checkout_destination_occupied',
|
|
93
|
+
'git_unavailable',
|
|
94
|
+
'workspace_prep_failed',
|
|
95
|
+
'setup_aborted',
|
|
96
|
+
'config_unresolvable',
|
|
97
|
+
'output_invalid',
|
|
98
|
+
'agent_config_invalid',
|
|
99
|
+
'agent_invocation_failed',
|
|
100
|
+
'agent_harness_unavailable',
|
|
101
|
+
'agent_inference_credentials_unavailable',
|
|
102
|
+
'agent_session_key_invalid',
|
|
103
|
+
'agent_session_held',
|
|
104
|
+
'agent_session_harness_mismatch',
|
|
105
|
+
'agent_session_unavailable',
|
|
106
|
+
'execution_payload_too_large',
|
|
107
|
+
'step_result_too_large',
|
|
108
|
+
'diagnostic_too_large',
|
|
109
|
+
'tool_error',
|
|
110
|
+
'tool_config_invalid',
|
|
111
|
+
'invocation_interrupted',
|
|
112
|
+
],
|
|
113
|
+
},
|
|
114
|
+
agent_config_issue: {
|
|
115
|
+
enum: [
|
|
116
|
+
'step_config_invalid',
|
|
117
|
+
'provider_not_configured',
|
|
118
|
+
'provider_unsupported',
|
|
119
|
+
'model_unavailable',
|
|
120
|
+
'credentials_invalid',
|
|
121
|
+
],
|
|
122
|
+
},
|
|
123
|
+
category: {enum: ['setup', 'user']},
|
|
124
|
+
},
|
|
125
|
+
});
|
|
126
|
+
expect(getStepAttemptResultJsonSchema.properties.gate_result.anyOf[0]).toMatchObject({
|
|
127
|
+
properties: {
|
|
128
|
+
kind: {
|
|
129
|
+
enum: [
|
|
130
|
+
'none',
|
|
131
|
+
'not_evaluated',
|
|
132
|
+
'passed',
|
|
133
|
+
'failed',
|
|
134
|
+
'uncheckable',
|
|
135
|
+
'evaluation_error',
|
|
136
|
+
'unknown',
|
|
137
|
+
],
|
|
138
|
+
},
|
|
139
|
+
},
|
|
140
|
+
});
|
|
141
|
+
expect(
|
|
142
|
+
listWorkflowRunJobExplanationsResultJsonSchema.properties.explanations.items.properties
|
|
143
|
+
.status,
|
|
144
|
+
).toMatchObject({enum: ['failed', 'skipped']});
|
|
145
|
+
expect(
|
|
146
|
+
getWorkflowExecutionContextResultJsonSchema.properties.oversized_fields.items.properties
|
|
147
|
+
.reason,
|
|
148
|
+
).toMatchObject({
|
|
149
|
+
enum: [
|
|
150
|
+
'legacy_value_exceeds_inline_limit',
|
|
151
|
+
'value_exceeds_inline_limit',
|
|
152
|
+
'value_truncated_at_write_limit',
|
|
153
|
+
],
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
expect(getWorkflowExecutionContextResultJsonSchema.properties.trigger_events).toMatchObject({
|
|
157
|
+
type: 'array',
|
|
158
|
+
maxItems: AGENT_ACCESS_PAGE_LIMIT_MAX,
|
|
159
|
+
});
|
|
160
|
+
expect(getWorkflowExecutionContextResultJsonSchema.properties.trigger_events_truncated).toEqual(
|
|
161
|
+
{const: true},
|
|
162
|
+
);
|
|
163
|
+
expect(getWorkflowExecutionContextResultJsonSchema.properties.condition_truncated).toEqual({
|
|
164
|
+
const: true,
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
expect(getStepAttemptResultJsonSchema.properties.response_text_truncated).toEqual({
|
|
168
|
+
const: true,
|
|
169
|
+
});
|
|
170
|
+
expect(getStepAttemptResultJsonSchema.properties.restart_feedback_truncated).toEqual({
|
|
171
|
+
const: true,
|
|
172
|
+
});
|
|
173
|
+
expect(listWorkflowRunJobExplanationsResultJsonSchema.properties.explanations).toMatchObject({
|
|
174
|
+
type: 'array',
|
|
175
|
+
maxItems: AGENT_ACCESS_PAGE_LIMIT_MAX,
|
|
176
|
+
});
|
|
177
|
+
});
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
function sourceAvailable() {
|
|
181
|
+
return {
|
|
182
|
+
kind: 'available' as const,
|
|
183
|
+
workflow_run_id: runId,
|
|
184
|
+
workflow_run_attempt: 1,
|
|
185
|
+
source_snapshot: {content: 'name: build', format: 'yaml' as const},
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
function sourceUnavailable() {
|
|
190
|
+
return {
|
|
191
|
+
kind: 'unavailable' as const,
|
|
192
|
+
workflow_run_id: runId,
|
|
193
|
+
workflow_run_attempt: 1,
|
|
194
|
+
reason: 'pre_snapshot_run' as const,
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
function contextResult() {
|
|
199
|
+
return {
|
|
200
|
+
workflow_run_id: runId,
|
|
201
|
+
workflow_run_attempt: 1,
|
|
202
|
+
job_id: jobId,
|
|
203
|
+
job_execution_id: executionId,
|
|
204
|
+
job_runner: ['runner-a'],
|
|
205
|
+
execution_runner: null,
|
|
206
|
+
job_outputs: {closed: {status: 'succeeded'}},
|
|
207
|
+
execution_outputs: {mapped: [{id: 1}]},
|
|
208
|
+
trigger_events: [
|
|
209
|
+
{
|
|
210
|
+
source: 'github',
|
|
211
|
+
event: 'push',
|
|
212
|
+
delivery_id: deliveryId,
|
|
213
|
+
received_at: isoDate,
|
|
214
|
+
project: {id: projectId},
|
|
215
|
+
repository: 'shipfox/app',
|
|
216
|
+
ref: 'refs/heads/main',
|
|
217
|
+
commit: 'abc123',
|
|
218
|
+
data: {message: 'external data'},
|
|
219
|
+
},
|
|
220
|
+
],
|
|
221
|
+
job_evaluation_trace: [
|
|
222
|
+
{
|
|
223
|
+
expression: 'steps.build.outputs.ok',
|
|
224
|
+
roots: ['steps.build.outputs.ok'],
|
|
225
|
+
fill_target: 'job.condition',
|
|
226
|
+
evaluated_at: isoDate,
|
|
227
|
+
field: 'condition',
|
|
228
|
+
value: 'true',
|
|
229
|
+
},
|
|
230
|
+
],
|
|
231
|
+
execution_evaluation_trace: null,
|
|
232
|
+
condition: 'steps.build.outputs.ok',
|
|
233
|
+
oversized_fields: [],
|
|
234
|
+
};
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
function stepResult() {
|
|
238
|
+
return {
|
|
239
|
+
workflow_run_id: runId,
|
|
240
|
+
workflow_run_attempt: 1,
|
|
241
|
+
job_id: jobId,
|
|
242
|
+
job_execution_id: executionId,
|
|
243
|
+
step_id: stepId,
|
|
244
|
+
step_attempt_id: stepAttemptId,
|
|
245
|
+
attempt: 1,
|
|
246
|
+
authored_config: {prompt: 'external data'},
|
|
247
|
+
config: null,
|
|
248
|
+
session: null,
|
|
249
|
+
evaluation_trace: null,
|
|
250
|
+
output: {value: 1},
|
|
251
|
+
outputs: {answer: 42},
|
|
252
|
+
response: 'done',
|
|
253
|
+
error: {message: 'tool failed', reason: 'tool_error' as const, category: 'user' as const},
|
|
254
|
+
gate_result: {kind: 'passed' as const, passed: true, source: 'test', exit_code: 0},
|
|
255
|
+
invocations: [{call_index: 0, started_at: isoDate}],
|
|
256
|
+
restart_feedback: null,
|
|
257
|
+
oversized_fields: [],
|
|
258
|
+
};
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
function explanationsResult() {
|
|
262
|
+
return {
|
|
263
|
+
workflow_run_id: runId,
|
|
264
|
+
workflow_run_attempt: 1,
|
|
265
|
+
explanations: [
|
|
266
|
+
{
|
|
267
|
+
job_id: jobId,
|
|
268
|
+
job_label: 'Build',
|
|
269
|
+
job_position: 0,
|
|
270
|
+
status: 'failed' as const,
|
|
271
|
+
status_reason: 'condition_errored',
|
|
272
|
+
evaluation_trace: null,
|
|
273
|
+
},
|
|
274
|
+
],
|
|
275
|
+
next_cursor: null,
|
|
276
|
+
};
|
|
277
|
+
}
|