@cleocode/lafs-protocol 1.4.1 โ 1.5.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/README.md +1 -1
- package/dist/schemas/v1/error-registry.json +9 -0
- package/dist/src/conformance.js +3 -2
- package/dist/src/fieldExtraction.d.ts +67 -0
- package/dist/src/fieldExtraction.js +133 -0
- package/dist/src/flagSemantics.d.ts +7 -3
- package/dist/src/flagSemantics.js +11 -1
- package/dist/src/index.d.ts +1 -0
- package/dist/src/index.js +1 -0
- package/dist/src/types.d.ts +2 -0
- package/dist/src/types.js +6 -1
- package/lafs.md +37 -8
- package/package.json +1 -1
- package/schemas/v1/error-registry.json +9 -0
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
LAFS defines a standard envelope format for structured responses from LLM-powered agents and tools. It complements transport protocols like [MCP](https://modelcontextprotocol.io/) and [A2A](https://github.com/google/A2A) by standardizing what comes back โ not how it gets there.
|
|
6
6
|
|
|
7
|
-
**Current version:** 1.
|
|
7
|
+
**Current version:** 1.5.0 | [๐ Documentation](https://codluv.gitbook.io/lafs-protocol/) | [Spec](lafs.md) | [Migration Guides](migrations/)
|
|
8
8
|
|
|
9
9
|
[](https://codluv.gitbook.io/lafs-protocol/)
|
|
10
10
|
[](https://www.npmjs.com/package/@cleocode/lafs-protocol)
|
|
@@ -109,6 +109,15 @@
|
|
|
109
109
|
"httpStatus": 413,
|
|
110
110
|
"grpcStatus": "RESOURCE_EXHAUSTED",
|
|
111
111
|
"cliExit": 2
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
"code": "E_FIELD_CONFLICT",
|
|
115
|
+
"category": "CONTRACT",
|
|
116
|
+
"description": "Mutually exclusive field selection modes (single-field extraction and multi-field filtering cannot be combined)",
|
|
117
|
+
"retryable": false,
|
|
118
|
+
"httpStatus": 400,
|
|
119
|
+
"grpcStatus": "INVALID_ARGUMENT",
|
|
120
|
+
"cliExit": 2
|
|
112
121
|
}
|
|
113
122
|
]
|
|
114
123
|
}
|
package/dist/src/conformance.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { getTransportMapping, isRegisteredErrorCode } from "./errorRegistry.js";
|
|
2
2
|
import { resolveOutputFormat, LAFSFlagError } from "./flagSemantics.js";
|
|
3
|
+
import { isMVILevel } from "./types.js";
|
|
3
4
|
import { getChecksForTier } from "./conformanceProfiles.js";
|
|
4
5
|
import { validateEnvelope } from "./validateEnvelope.js";
|
|
5
6
|
function pushCheck(checks, name, pass, detail) {
|
|
@@ -75,8 +76,8 @@ export function runEnvelopeConformance(envelope, options = {}) {
|
|
|
75
76
|
}
|
|
76
77
|
}
|
|
77
78
|
}
|
|
78
|
-
const
|
|
79
|
-
pushCheck(checks, "meta_mvi_present",
|
|
79
|
+
const mviValid = isMVILevel(typed._meta.mvi);
|
|
80
|
+
pushCheck(checks, "meta_mvi_present", mviValid, mviValid ? undefined : `invalid mvi level: ${String(typed._meta.mvi)}`);
|
|
80
81
|
pushCheck(checks, "meta_strict_present", typeof typed._meta.strict === "boolean");
|
|
81
82
|
// strict_mode_behavior: when strict=true, the envelope MUST NOT contain
|
|
82
83
|
// explicit null for optional fields that can be omitted (page, error on success).
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import type { LAFSEnvelope, MVILevel } from "./types.js";
|
|
2
|
+
export interface FieldExtractionInput {
|
|
3
|
+
/** --field <name>: extract single field as plain text, no envelope */
|
|
4
|
+
fieldFlag?: string;
|
|
5
|
+
/** --fields <a,b,c>: filter result to these fields, preserve envelope */
|
|
6
|
+
fieldsFlag?: string | string[];
|
|
7
|
+
/** --mvi <level>: envelope verbosity (client-requestable levels only) */
|
|
8
|
+
mviFlag?: MVILevel | string;
|
|
9
|
+
}
|
|
10
|
+
export interface FieldExtractionResolution {
|
|
11
|
+
/** When set: extract this field as plain text, discard envelope. */
|
|
12
|
+
field?: string;
|
|
13
|
+
/** When set: filter result to these fields (envelope preserved). */
|
|
14
|
+
fields?: string[];
|
|
15
|
+
/** Resolved MVI level. Defaults to 'standard'. */
|
|
16
|
+
mvi: MVILevel;
|
|
17
|
+
/** Which input determined the mvi value: 'flag' when mviFlag was valid, 'default' otherwise. */
|
|
18
|
+
mviSource: "flag" | "default";
|
|
19
|
+
/**
|
|
20
|
+
* True when _fields are requested, indicating the server SHOULD set
|
|
21
|
+
* _meta.mvi = 'custom' in the response per ยง9.1.
|
|
22
|
+
* Separate from the client-resolved mvi level.
|
|
23
|
+
*/
|
|
24
|
+
expectsCustomMvi: boolean;
|
|
25
|
+
}
|
|
26
|
+
export declare function resolveFieldExtraction(input: FieldExtractionInput): FieldExtractionResolution;
|
|
27
|
+
/**
|
|
28
|
+
* Extract a named field from a LAFS result object.
|
|
29
|
+
*
|
|
30
|
+
* Handles four result shapes:
|
|
31
|
+
* 1. Direct array: result[0][field] (list operations where result IS an array)
|
|
32
|
+
* 2. Direct: result[field] (flat result object)
|
|
33
|
+
* 3. Nested: result.<key>[field] (wrapper-entity, e.g. result.task.title)
|
|
34
|
+
* 4. Array value: result.<key>[0][field] (wrapper-array, e.g. result.items[0].title)
|
|
35
|
+
*
|
|
36
|
+
* Returns the value from the first match only. For array results (shapes 1
|
|
37
|
+
* and 4), returns the first element's field value only. To extract from all
|
|
38
|
+
* elements, iterate the array or use applyFieldFilter().
|
|
39
|
+
*
|
|
40
|
+
* When multiple wrapper keys contain the requested field (shapes 3 and 4),
|
|
41
|
+
* the first key in property insertion order wins.
|
|
42
|
+
*
|
|
43
|
+
* Returns undefined if not found at any level.
|
|
44
|
+
*/
|
|
45
|
+
export declare function extractFieldFromResult(result: LAFSEnvelope['result'], field: string): unknown;
|
|
46
|
+
/** Convenience wrapper โ extracts a field from an envelope's result. */
|
|
47
|
+
export declare function extractFieldFromEnvelope(envelope: LAFSEnvelope, field: string): unknown;
|
|
48
|
+
/**
|
|
49
|
+
* Filter result fields in a LAFS envelope to the requested subset.
|
|
50
|
+
*
|
|
51
|
+
* Handles the same four result shapes as extractFieldFromResult:
|
|
52
|
+
* 1. Direct array: project each element
|
|
53
|
+
* 2. Flat result: project top-level keys
|
|
54
|
+
* 3. Wrapper-entity: project nested entity's keys, preserve wrapper
|
|
55
|
+
* 4. Wrapper-array: project each element's keys, preserve wrapper
|
|
56
|
+
*
|
|
57
|
+
* Sets _meta.mvi = 'custom' per ยง9.1.
|
|
58
|
+
* Returns a new envelope with a new _meta object. Result values are not
|
|
59
|
+
* deep-cloned; nested object references are shared with the original.
|
|
60
|
+
* Unknown field names are silently omitted per ยง9.2.
|
|
61
|
+
*
|
|
62
|
+
* When result is a wrapper (shapes 3/4) with multiple keys, each key is
|
|
63
|
+
* projected independently. Primitive values at the wrapper level (numbers,
|
|
64
|
+
* strings, booleans) are preserved as-is โ _fields is applied to nested
|
|
65
|
+
* entity or array keys only, not to the wrapper's own primitive keys.
|
|
66
|
+
*/
|
|
67
|
+
export declare function applyFieldFilter(envelope: LAFSEnvelope, fields: string[]): LAFSEnvelope;
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import { LAFSFlagError } from "./flagSemantics.js";
|
|
2
|
+
import { isMVILevel } from "./types.js";
|
|
3
|
+
export function resolveFieldExtraction(input) {
|
|
4
|
+
if (input.fieldFlag && input.fieldsFlag) {
|
|
5
|
+
throw new LAFSFlagError('E_FIELD_CONFLICT', 'Cannot combine --field and --fields: --field extracts a single value '
|
|
6
|
+
+ 'as plain text (no envelope); --fields filters the JSON envelope. '
|
|
7
|
+
+ 'Use one or the other.', { conflictingModes: ['single-field-extraction', 'multi-field-filter'] });
|
|
8
|
+
}
|
|
9
|
+
const fields = typeof input.fieldsFlag === 'string'
|
|
10
|
+
? input.fieldsFlag.split(',').map(f => f.trim()).filter(Boolean)
|
|
11
|
+
: Array.isArray(input.fieldsFlag)
|
|
12
|
+
? input.fieldsFlag.map(f => f.trim()).filter(Boolean)
|
|
13
|
+
: undefined;
|
|
14
|
+
// 'custom' is server-set (ยง9.1) โ not a client-requestable level
|
|
15
|
+
const validMvi = isMVILevel(input.mviFlag) && input.mviFlag !== 'custom';
|
|
16
|
+
const mvi = validMvi ? input.mviFlag : 'standard';
|
|
17
|
+
const mviSource = validMvi ? 'flag' : 'default';
|
|
18
|
+
const hasFields = (fields?.length ?? 0) > 0;
|
|
19
|
+
return {
|
|
20
|
+
field: input.fieldFlag || undefined,
|
|
21
|
+
fields: hasFields ? fields : undefined,
|
|
22
|
+
mvi,
|
|
23
|
+
mviSource,
|
|
24
|
+
expectsCustomMvi: hasFields,
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Extract a named field from a LAFS result object.
|
|
29
|
+
*
|
|
30
|
+
* Handles four result shapes:
|
|
31
|
+
* 1. Direct array: result[0][field] (list operations where result IS an array)
|
|
32
|
+
* 2. Direct: result[field] (flat result object)
|
|
33
|
+
* 3. Nested: result.<key>[field] (wrapper-entity, e.g. result.task.title)
|
|
34
|
+
* 4. Array value: result.<key>[0][field] (wrapper-array, e.g. result.items[0].title)
|
|
35
|
+
*
|
|
36
|
+
* Returns the value from the first match only. For array results (shapes 1
|
|
37
|
+
* and 4), returns the first element's field value only. To extract from all
|
|
38
|
+
* elements, iterate the array or use applyFieldFilter().
|
|
39
|
+
*
|
|
40
|
+
* When multiple wrapper keys contain the requested field (shapes 3 and 4),
|
|
41
|
+
* the first key in property insertion order wins.
|
|
42
|
+
*
|
|
43
|
+
* Returns undefined if not found at any level.
|
|
44
|
+
*/
|
|
45
|
+
export function extractFieldFromResult(result, field) {
|
|
46
|
+
if (result === null || typeof result !== 'object')
|
|
47
|
+
return undefined;
|
|
48
|
+
// Shape 1: result is a direct array
|
|
49
|
+
if (Array.isArray(result)) {
|
|
50
|
+
if (result.length === 0)
|
|
51
|
+
return undefined;
|
|
52
|
+
const first = result[0];
|
|
53
|
+
if (first && typeof first === 'object' && field in first)
|
|
54
|
+
return first[field];
|
|
55
|
+
return undefined;
|
|
56
|
+
}
|
|
57
|
+
// Shape 2: direct property on result object
|
|
58
|
+
const record = result;
|
|
59
|
+
if (field in record)
|
|
60
|
+
return record[field];
|
|
61
|
+
// Shapes 3 & 4: one level down (first matching key in insertion order wins)
|
|
62
|
+
for (const value of Object.values(record)) {
|
|
63
|
+
if (value && typeof value === 'object' && !Array.isArray(value)) {
|
|
64
|
+
const nested = value;
|
|
65
|
+
if (field in nested)
|
|
66
|
+
return nested[field];
|
|
67
|
+
}
|
|
68
|
+
if (Array.isArray(value) && value.length > 0) {
|
|
69
|
+
const first = value[0];
|
|
70
|
+
if (first && typeof first === 'object' && field in first)
|
|
71
|
+
return first[field];
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
return undefined;
|
|
75
|
+
}
|
|
76
|
+
/** Convenience wrapper โ extracts a field from an envelope's result. */
|
|
77
|
+
export function extractFieldFromEnvelope(envelope, field) {
|
|
78
|
+
return extractFieldFromResult(envelope.result, field);
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Filter result fields in a LAFS envelope to the requested subset.
|
|
82
|
+
*
|
|
83
|
+
* Handles the same four result shapes as extractFieldFromResult:
|
|
84
|
+
* 1. Direct array: project each element
|
|
85
|
+
* 2. Flat result: project top-level keys
|
|
86
|
+
* 3. Wrapper-entity: project nested entity's keys, preserve wrapper
|
|
87
|
+
* 4. Wrapper-array: project each element's keys, preserve wrapper
|
|
88
|
+
*
|
|
89
|
+
* Sets _meta.mvi = 'custom' per ยง9.1.
|
|
90
|
+
* Returns a new envelope with a new _meta object. Result values are not
|
|
91
|
+
* deep-cloned; nested object references are shared with the original.
|
|
92
|
+
* Unknown field names are silently omitted per ยง9.2.
|
|
93
|
+
*
|
|
94
|
+
* When result is a wrapper (shapes 3/4) with multiple keys, each key is
|
|
95
|
+
* projected independently. Primitive values at the wrapper level (numbers,
|
|
96
|
+
* strings, booleans) are preserved as-is โ _fields is applied to nested
|
|
97
|
+
* entity or array keys only, not to the wrapper's own primitive keys.
|
|
98
|
+
*/
|
|
99
|
+
export function applyFieldFilter(envelope, fields) {
|
|
100
|
+
if (fields.length === 0 || envelope.result === null)
|
|
101
|
+
return envelope;
|
|
102
|
+
const pick = (obj) => Object.fromEntries(fields.filter(f => f in obj).map(f => [f, obj[f]]));
|
|
103
|
+
let filtered;
|
|
104
|
+
if (Array.isArray(envelope.result)) {
|
|
105
|
+
// Shape 1: direct array
|
|
106
|
+
filtered = envelope.result.map(pick);
|
|
107
|
+
}
|
|
108
|
+
else {
|
|
109
|
+
const record = envelope.result;
|
|
110
|
+
const topLevelMatch = fields.some(f => f in record);
|
|
111
|
+
if (topLevelMatch) {
|
|
112
|
+
// Shape 2: flat result
|
|
113
|
+
filtered = pick(record);
|
|
114
|
+
}
|
|
115
|
+
else {
|
|
116
|
+
// Shapes 3 & 4: wrapper โ apply pick one level down, preserve wrapper keys
|
|
117
|
+
filtered = Object.fromEntries(Object.entries(record).map(([k, v]) => {
|
|
118
|
+
if (Array.isArray(v)) {
|
|
119
|
+
return [k, v.map(item => pick(item))];
|
|
120
|
+
}
|
|
121
|
+
if (v && typeof v === 'object') {
|
|
122
|
+
return [k, pick(v)];
|
|
123
|
+
}
|
|
124
|
+
return [k, v];
|
|
125
|
+
}));
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
return {
|
|
129
|
+
...envelope,
|
|
130
|
+
_meta: { ...envelope._meta, mvi: 'custom' },
|
|
131
|
+
result: filtered,
|
|
132
|
+
};
|
|
133
|
+
}
|
|
@@ -1,12 +1,16 @@
|
|
|
1
|
-
import type { FlagInput } from "./types.js";
|
|
1
|
+
import type { FlagInput, LAFSError, LAFSErrorCategory } from "./types.js";
|
|
2
2
|
export interface FlagResolution {
|
|
3
3
|
format: "json" | "human";
|
|
4
4
|
source: "flag" | "project" | "user" | "default";
|
|
5
5
|
/** When true, suppress non-essential output for scripting */
|
|
6
6
|
quiet: boolean;
|
|
7
7
|
}
|
|
8
|
-
export declare class LAFSFlagError extends Error {
|
|
8
|
+
export declare class LAFSFlagError extends Error implements LAFSError {
|
|
9
9
|
code: string;
|
|
10
|
-
|
|
10
|
+
category: LAFSErrorCategory;
|
|
11
|
+
retryable: boolean;
|
|
12
|
+
retryAfterMs: number | null;
|
|
13
|
+
details: Record<string, unknown>;
|
|
14
|
+
constructor(code: string, message: string, details?: Record<string, unknown>);
|
|
11
15
|
}
|
|
12
16
|
export declare function resolveOutputFormat(input: FlagInput): FlagResolution;
|
|
@@ -1,9 +1,19 @@
|
|
|
1
|
+
import { getRegistryCode } from "./errorRegistry.js";
|
|
1
2
|
export class LAFSFlagError extends Error {
|
|
2
3
|
code;
|
|
3
|
-
|
|
4
|
+
category;
|
|
5
|
+
retryable;
|
|
6
|
+
retryAfterMs;
|
|
7
|
+
details;
|
|
8
|
+
constructor(code, message, details = {}) {
|
|
4
9
|
super(message);
|
|
5
10
|
this.name = "LAFSFlagError";
|
|
6
11
|
this.code = code;
|
|
12
|
+
const entry = getRegistryCode(code);
|
|
13
|
+
this.category = (entry?.category ?? "CONTRACT");
|
|
14
|
+
this.retryable = entry?.retryable ?? false;
|
|
15
|
+
this.retryAfterMs = null;
|
|
16
|
+
this.details = details;
|
|
7
17
|
}
|
|
8
18
|
}
|
|
9
19
|
export function resolveOutputFormat(input) {
|
package/dist/src/index.d.ts
CHANGED
|
@@ -4,6 +4,7 @@ export * from "./deprecationRegistry.js";
|
|
|
4
4
|
export * from "./validateEnvelope.js";
|
|
5
5
|
export * from "./envelope.js";
|
|
6
6
|
export * from "./flagSemantics.js";
|
|
7
|
+
export * from "./fieldExtraction.js";
|
|
7
8
|
export * from "./conformance.js";
|
|
8
9
|
export * from "./conformanceProfiles.js";
|
|
9
10
|
export * from "./compliance.js";
|
package/dist/src/index.js
CHANGED
|
@@ -4,6 +4,7 @@ export * from "./deprecationRegistry.js";
|
|
|
4
4
|
export * from "./validateEnvelope.js";
|
|
5
5
|
export * from "./envelope.js";
|
|
6
6
|
export * from "./flagSemantics.js";
|
|
7
|
+
export * from "./fieldExtraction.js";
|
|
7
8
|
export * from "./conformance.js";
|
|
8
9
|
export * from "./conformanceProfiles.js";
|
|
9
10
|
export * from "./compliance.js";
|
package/dist/src/types.d.ts
CHANGED
|
@@ -8,6 +8,8 @@ export interface Warning {
|
|
|
8
8
|
removeBy?: string;
|
|
9
9
|
}
|
|
10
10
|
export type MVILevel = 'minimal' | 'standard' | 'full' | 'custom';
|
|
11
|
+
export declare const MVI_LEVELS: ReadonlySet<MVILevel>;
|
|
12
|
+
export declare function isMVILevel(value: unknown): value is MVILevel;
|
|
11
13
|
export interface LAFSMeta {
|
|
12
14
|
specVersion: string;
|
|
13
15
|
schemaVersion: string;
|
package/dist/src/types.js
CHANGED
package/lafs.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# LAFS: LLM-Agent-First Specification
|
|
2
2
|
|
|
3
3
|
> ๐ **Documentation:** https://codluv.gitbook.io/lafs-protocol/
|
|
4
|
-
> **Version:** 1.
|
|
4
|
+
> **Version:** 1.5.0 | **Status:** Production Ready
|
|
5
5
|
|
|
6
6
|
## 1. Scope
|
|
7
7
|
|
|
@@ -431,16 +431,45 @@ To reduce token and I/O overhead, implementations SHOULD support lazy retrieval
|
|
|
431
431
|
- Default list/batch outputs MUST only contain fields required for next action.
|
|
432
432
|
- Verbose fields SHOULD be omitted by default.
|
|
433
433
|
- Systems SHOULD publish operation-level MVI budgets.
|
|
434
|
+
- `_meta.mvi` MUST be one of: `minimal`, `standard`, `full`, or `custom`.
|
|
435
|
+
- `_meta` is a structural envelope field and MUST always be present regardless
|
|
436
|
+
of `mvi` level. MVI levels govern the contents of `result` only; they MUST NOT
|
|
437
|
+
affect envelope structural fields (`$schema`, `_meta`, `success`, `error`,
|
|
438
|
+
`page`, `_extensions`).
|
|
439
|
+
- `minimal`: MUST include only fields within `result` sufficient for the next
|
|
440
|
+
agent action (typically identifiers and status). Implementations SHOULD
|
|
441
|
+
document which fields constitute `minimal` per operation.
|
|
442
|
+
- `standard` (default): MUST include all commonly useful fields for the
|
|
443
|
+
operation.
|
|
444
|
+
- `full`: MUST include all available fields including verbose and
|
|
445
|
+
rarely-accessed data.
|
|
446
|
+
- `custom`: MUST be set by the server when `_fields` projection has been
|
|
447
|
+
applied, indicating the result does not conform to any predefined disclosure
|
|
448
|
+
level. `custom` is not a client-requestable level.
|
|
434
449
|
|
|
435
450
|
### 9.2 Field selection (`_fields`)
|
|
436
451
|
|
|
437
|
-
Clients MAY request a subset of response fields via the `_fields` request
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
-
|
|
441
|
-
|
|
442
|
-
-
|
|
443
|
-
- `
|
|
452
|
+
Clients MAY request a subset of response fields via the `_fields` request
|
|
453
|
+
parameter.
|
|
454
|
+
|
|
455
|
+
- `_fields` MUST be an array of strings identifying `result` field names.
|
|
456
|
+
Path notation (e.g., `task.title`) is not defined by this specification.
|
|
457
|
+
- When `result` is an array, `_fields` applies to the keys of each element.
|
|
458
|
+
- When `result` is a wrapper object whose values are entities or arrays of
|
|
459
|
+
entities (e.g., `{ "task": { ... } }` or `{ "items": [...] }`), servers
|
|
460
|
+
SHOULD apply `_fields` to the nested entity fields rather than the wrapper's
|
|
461
|
+
own keys.
|
|
462
|
+
- When `_fields` is present, the server MUST return only the requested fields
|
|
463
|
+
plus any MVI-required fields for the declared disclosure level.
|
|
464
|
+
The server MUST set `_meta.mvi` to `custom` in the response.
|
|
465
|
+
- When `_fields` is absent, the server MUST return fields appropriate for the
|
|
466
|
+
declared `_meta.mvi` disclosure level.
|
|
467
|
+
- If a requested field does not exist on the resource, the server SHOULD omit
|
|
468
|
+
it silently (no error). Servers MAY include a warning in `_meta.warnings`
|
|
469
|
+
for unknown fields.
|
|
470
|
+
- `_fields` MUST NOT affect envelope structural fields (`$schema`, `_meta`,
|
|
471
|
+
`success`, `error`, `page`, `_extensions`); it applies only to the contents
|
|
472
|
+
of `result`.
|
|
444
473
|
|
|
445
474
|
### 9.3 Expansion mechanism (`_expand`)
|
|
446
475
|
|
package/package.json
CHANGED
|
@@ -109,6 +109,15 @@
|
|
|
109
109
|
"httpStatus": 413,
|
|
110
110
|
"grpcStatus": "RESOURCE_EXHAUSTED",
|
|
111
111
|
"cliExit": 2
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
"code": "E_FIELD_CONFLICT",
|
|
115
|
+
"category": "CONTRACT",
|
|
116
|
+
"description": "Mutually exclusive field selection modes (single-field extraction and multi-field filtering cannot be combined)",
|
|
117
|
+
"retryable": false,
|
|
118
|
+
"httpStatus": 400,
|
|
119
|
+
"grpcStatus": "INVALID_ARGUMENT",
|
|
120
|
+
"cliExit": 2
|
|
112
121
|
}
|
|
113
122
|
]
|
|
114
123
|
}
|