@cleocode/lafs-protocol 0.5.0 → 1.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.
Files changed (48) hide show
  1. package/LICENSE +0 -0
  2. package/README.md +7 -3
  3. package/dist/examples/discovery-server.d.ts +8 -0
  4. package/dist/examples/discovery-server.js +216 -0
  5. package/dist/examples/mcp-lafs-client.d.ts +10 -0
  6. package/dist/examples/mcp-lafs-client.js +427 -0
  7. package/dist/examples/mcp-lafs-server.d.ts +10 -0
  8. package/dist/examples/mcp-lafs-server.js +358 -0
  9. package/dist/schemas/v1/envelope.schema.json +0 -0
  10. package/dist/schemas/v1/error-registry.json +0 -0
  11. package/dist/src/a2a/bridge.d.ts +129 -0
  12. package/dist/src/a2a/bridge.js +173 -0
  13. package/dist/src/a2a/index.d.ts +36 -0
  14. package/dist/src/a2a/index.js +36 -0
  15. package/dist/src/budgetEnforcement.d.ts +84 -0
  16. package/dist/src/budgetEnforcement.js +328 -0
  17. package/dist/src/circuit-breaker/index.d.ts +121 -0
  18. package/dist/src/circuit-breaker/index.js +249 -0
  19. package/dist/src/cli.d.ts +0 -0
  20. package/dist/src/cli.js +0 -0
  21. package/dist/src/conformance.d.ts +0 -0
  22. package/dist/src/conformance.js +0 -0
  23. package/dist/src/discovery.d.ts +127 -0
  24. package/dist/src/discovery.js +304 -0
  25. package/dist/src/errorRegistry.d.ts +0 -0
  26. package/dist/src/errorRegistry.js +0 -0
  27. package/dist/src/flagSemantics.d.ts +0 -0
  28. package/dist/src/flagSemantics.js +0 -0
  29. package/dist/src/health/index.d.ts +105 -0
  30. package/dist/src/health/index.js +211 -0
  31. package/dist/src/index.d.ts +8 -0
  32. package/dist/src/index.js +10 -0
  33. package/dist/src/mcpAdapter.d.ts +28 -0
  34. package/dist/src/mcpAdapter.js +281 -0
  35. package/dist/src/shutdown/index.d.ts +69 -0
  36. package/dist/src/shutdown/index.js +160 -0
  37. package/dist/src/tokenEstimator.d.ts +87 -0
  38. package/dist/src/tokenEstimator.js +238 -0
  39. package/dist/src/types.d.ts +25 -0
  40. package/dist/src/types.js +0 -0
  41. package/dist/src/validateEnvelope.d.ts +0 -0
  42. package/dist/src/validateEnvelope.js +0 -0
  43. package/lafs.md +167 -0
  44. package/package.json +10 -4
  45. package/schemas/v1/context-ledger.schema.json +0 -0
  46. package/schemas/v1/discovery.schema.json +132 -0
  47. package/schemas/v1/envelope.schema.json +0 -0
  48. package/schemas/v1/error-registry.json +0 -0
package/lafs.md CHANGED
@@ -1,5 +1,8 @@
1
1
  # LAFS: LLM-Agent-First Specification
2
2
 
3
+ > 📚 **Documentation:** https://codluv.gitbook.io/lafs-protocol/
4
+ > **Version:** 1.0.0 | **Status:** Production Ready
5
+
3
6
  ## 1. Scope
4
7
 
5
8
  LAFS is a **response envelope contract specification**. It defines the canonical shape of structured responses — success envelopes, error envelopes, pagination metadata, and context preservation — for software systems whose primary consumer is an LLM agent or AI-driven tool.
@@ -176,6 +179,56 @@ Rules:
176
179
  - Decisions affecting output MUST be represented in ledger state.
177
180
  - Missing required context for a mutating step MUST fail with structured error.
178
181
 
182
+ ### 8.1 Context Retrieval
183
+
184
+ Agents MAY retrieve context ledger state via `GET /_lafs/context/{ledgerId}` with projection modes.
185
+
186
+ #### 8.1.1 Projection Modes
187
+
188
+ **Full Mode (`mode=full`):**
189
+ Returns complete ledger including all entries.
190
+ - Use for: Initial loads, recovery scenarios
191
+ - Supports: Offset-based pagination
192
+ - Response includes: All ledger fields
193
+
194
+ **Delta Mode (`mode=delta&sinceVersion=N`):**
195
+ Returns only entries added since version N.
196
+ - Use for: Active workflows (efficient sync)
197
+ - Response includes:
198
+ ```json
199
+ {
200
+ "ledgerId": "ctx_abc123",
201
+ "mode": "delta",
202
+ "fromVersion": 10,
203
+ "toVersion": 15,
204
+ "entries": [/* new entries only */],
205
+ "removedConstraints": [/* constraints no longer active */],
206
+ "checksum": "sha256:..."
207
+ }
208
+ ```
209
+
210
+ **Summary Mode (`mode=summary`):**
211
+ Returns checksum and version for validation.
212
+ - Use for: Quick sync validation
213
+ - Response includes only: `ledgerId`, `version`, `checksum`, `entryCount`
214
+
215
+ #### 8.1.2 Query Parameters
216
+
217
+ | Parameter | Type | Description |
218
+ |-----------|------|-------------|
219
+ | `mode` | enum | `full`, `delta`, `summary` |
220
+ | `sinceVersion` | integer | For delta mode: return entries after this version |
221
+ | `filterByOperation` | string[] | Filter entries by operation name(s) |
222
+ | `limit` | integer | Max entries (1-1000, default 100) |
223
+ | `includeChecksum` | boolean | Include integrity checksum (default true) |
224
+
225
+ #### 8.1.3 Agent Guidance
226
+
227
+ - **Initial load**: Use `mode=full` once
228
+ - **Active workflows**: Use `mode=delta` with last known version
229
+ - **Validation**: Use `mode=summary` to verify sync state
230
+ - **Default recommendation**: `delta` mode for agent-optimal behavior
231
+
179
232
  ---
180
233
 
181
234
  ## 9. MVI and Progressive Disclosure
@@ -212,6 +265,120 @@ Clients MAY request expanded/nested data via the `_expand` request parameter.
212
265
  - Pagination mode (offset or cursor) MUST be documented.
213
266
  - Mixed pagination modes in one request MUST fail validation.
214
267
 
268
+ ### 9.5 Token Budget Signaling
269
+
270
+ Token budget signaling enables clients to declare resource constraints that servers MUST respect when generating responses. This mechanism prevents context window overflow in LLM-driven workflows.
271
+
272
+ #### 9.5.1 Budget Declaration (`_budget`)
273
+
274
+ Clients MAY declare resource constraints via the `_budget` request parameter:
275
+
276
+ ```json
277
+ {
278
+ "_budget": {
279
+ "maxTokens": 4000,
280
+ "maxBytes": 32768,
281
+ "maxItems": 100
282
+ }
283
+ }
284
+ ```
285
+
286
+ **Fields:**
287
+ - `maxTokens` (integer) - Maximum approximate tokens
288
+ - `maxBytes` (integer) - Maximum byte size
289
+ - `maxItems` (integer) - Maximum items in lists
290
+
291
+ **Constraints:**
292
+ - At least one field MUST be present
293
+ - All values MUST be positive integers
294
+ - Servers MAY reject budgets exceeding implementation limits
295
+
296
+ #### 9.5.2 Server Behavior
297
+
298
+ Servers MUST:
299
+ 1. Parse `_budget` from incoming requests
300
+ 2. Estimate/measure response size
301
+ 3. Return response within budget OR fail with `E_MVI_BUDGET_EXCEEDED`
302
+
303
+ Servers MAY truncate responses using:
304
+ - **Depth-first**: Remove deepest nested fields
305
+ - **Field priority**: Remove non-essential fields first
306
+ - **Hybrid**: Combine both strategies
307
+
308
+ When truncation occurs, servers MUST include:
309
+ ```json
310
+ {
311
+ "_meta": {
312
+ "warnings": [{
313
+ "code": "E_MVI_BUDGET_TRUNCATED",
314
+ "message": "Response truncated to fit token budget"
315
+ }],
316
+ "_tokenEstimate": {
317
+ "estimated": 2847,
318
+ "budget": 4000,
319
+ "method": "character_based"
320
+ }
321
+ }
322
+ }
323
+ ```
324
+
325
+ #### 9.5.3 Error Specification
326
+
327
+ **E_MVI_BUDGET_EXCEEDED:**
328
+ - **Category:** `VALIDATION`
329
+ - **Retryable:** `true`
330
+ - **Details:** `estimatedTokens`, `budget`, `excessTokens`, `constraint`
331
+
332
+ ```json
333
+ {
334
+ "error": {
335
+ "code": "E_MVI_BUDGET_EXCEEDED",
336
+ "message": "Response exceeds declared token budget",
337
+ "category": "VALIDATION",
338
+ "retryable": true,
339
+ "details": {
340
+ "estimatedTokens": 5234,
341
+ "budget": 4000,
342
+ "excessTokens": 1234,
343
+ "constraint": "maxTokens"
344
+ }
345
+ }
346
+ }
347
+ ```
348
+
349
+ #### 9.5.4 Token Estimation Algorithm (Normative)
350
+
351
+ Servers MUST implement this algorithm or equivalent (within +/- 10%):
352
+
353
+ ```
354
+ FUNCTION estimate_tokens(value, depth = 0):
355
+ IF depth > 20: RETURN INFINITY
356
+ IF value IS null: RETURN 1
357
+ IF value IS boolean: RETURN 1
358
+ IF value IS number: RETURN max(1, len(stringify(value)) / 4)
359
+ IF value IS string:
360
+ graphemes = count_grapheme_clusters(value)
361
+ RETURN max(1, graphemes / 4.0)
362
+ IF value IS array:
363
+ tokens = 2 // []
364
+ FOR item IN value:
365
+ tokens += estimate_tokens(item, depth + 1) + 1
366
+ RETURN tokens
367
+ IF value IS object:
368
+ tokens = 2 // {}
369
+ FOR key, val IN value:
370
+ tokens += estimate_tokens(key, depth + 1)
371
+ tokens += 2 // : and ,
372
+ tokens += estimate_tokens(val, depth + 1)
373
+ RETURN tokens
374
+ ```
375
+
376
+ **Requirements:**
377
+ - Count grapheme clusters (not bytes) for unicode
378
+ - Enforce max depth of 20
379
+ - Handle circular references
380
+ - Complete within 10ms for 100KB payloads
381
+
215
382
  ---
216
383
 
217
384
  ## 10. Strictness
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cleocode/lafs-protocol",
3
- "version": "0.5.0",
3
+ "version": "1.1.0",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "description": "LLM-Agent-First Specification schemas and conformance tooling",
@@ -23,7 +23,7 @@
23
23
  "type": "git",
24
24
  "url": "git+https://github.com/kryptobaseddev/lafs-protocol.git"
25
25
  },
26
- "homepage": "https://github.com/kryptobaseddev/lafs-protocol#readme",
26
+ "homepage": "https://codluv.gitbook.io/lafs-protocol/",
27
27
  "bugs": {
28
28
  "url": "https://github.com/kryptobaseddev/lafs-protocol/issues"
29
29
  },
@@ -50,13 +50,19 @@
50
50
  ],
51
51
  "license": "MIT",
52
52
  "devDependencies": {
53
+ "@modelcontextprotocol/sdk": "^1.26.0",
54
+ "@types/express": "^5.0.6",
53
55
  "@types/node": "^24.3.0",
56
+ "@types/supertest": "^6.0.3",
57
+ "supertest": "^7.2.2",
54
58
  "tsx": "^4.20.5",
55
59
  "typescript": "^5.9.2",
56
60
  "vitest": "^2.1.9"
57
61
  },
58
62
  "dependencies": {
59
- "ajv": "^8.17.1",
60
- "ajv-formats": "^3.0.1"
63
+ "@a2a-js/sdk": "^0.3.10",
64
+ "ajv": "^8.18.0",
65
+ "ajv-formats": "^3.0.1",
66
+ "express": "^5.2.1"
61
67
  }
62
68
  }
File without changes
@@ -0,0 +1,132 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema#",
3
+ "$id": "https://lafs.dev/schemas/v1/discovery.schema.json",
4
+ "title": "LAFS Discovery Document",
5
+ "description": "Schema for LAFS agent discovery documents served at /.well-known/lafs.json",
6
+ "type": "object",
7
+ "required": [
8
+ "$schema",
9
+ "lafs_version",
10
+ "service",
11
+ "capabilities",
12
+ "endpoints"
13
+ ],
14
+ "properties": {
15
+ "$schema": {
16
+ "type": "string",
17
+ "format": "uri",
18
+ "description": "URL of the schema this document conforms to"
19
+ },
20
+ "lafs_version": {
21
+ "type": "string",
22
+ "pattern": "^\\d+\\.\\d+\\.\\d+$",
23
+ "description": "LAFS protocol version (semantic versioning)"
24
+ },
25
+ "service": {
26
+ "type": "object",
27
+ "description": "Service identification and metadata",
28
+ "required": [
29
+ "name",
30
+ "version"
31
+ ],
32
+ "properties": {
33
+ "name": {
34
+ "type": "string",
35
+ "minLength": 1,
36
+ "maxLength": 100,
37
+ "description": "Unique service name (kebab-case recommended)"
38
+ },
39
+ "version": {
40
+ "type": "string",
41
+ "pattern": "^\\d+\\.\\d+\\.\\d+$",
42
+ "description": "Service version (semantic versioning)"
43
+ },
44
+ "description": {
45
+ "type": "string",
46
+ "maxLength": 500,
47
+ "description": "Human-readable service description"
48
+ }
49
+ },
50
+ "additionalProperties": false
51
+ },
52
+ "capabilities": {
53
+ "type": "array",
54
+ "description": "List of LAFS capabilities this service provides",
55
+ "minItems": 1,
56
+ "items": {
57
+ "type": "object",
58
+ "required": [
59
+ "name",
60
+ "version",
61
+ "operations"
62
+ ],
63
+ "properties": {
64
+ "name": {
65
+ "type": "string",
66
+ "minLength": 1,
67
+ "maxLength": 100,
68
+ "description": "Capability identifier (kebab-case recommended)"
69
+ },
70
+ "version": {
71
+ "type": "string",
72
+ "pattern": "^\\d+\\.\\d+\\.\\d+$",
73
+ "description": "Capability version (semantic versioning)"
74
+ },
75
+ "description": {
76
+ "type": "string",
77
+ "maxLength": 500,
78
+ "description": "Human-readable capability description"
79
+ },
80
+ "operations": {
81
+ "type": "array",
82
+ "description": "List of operations this capability supports",
83
+ "minItems": 1,
84
+ "items": {
85
+ "type": "string",
86
+ "minLength": 1,
87
+ "maxLength": 50
88
+ }
89
+ },
90
+ "optional": {
91
+ "type": "boolean",
92
+ "default": false,
93
+ "description": "Whether this capability is optional for clients"
94
+ }
95
+ },
96
+ "additionalProperties": false
97
+ }
98
+ },
99
+ "endpoints": {
100
+ "type": "object",
101
+ "description": "URL endpoints for LAFS operations",
102
+ "required": [
103
+ "envelope",
104
+ "discovery"
105
+ ],
106
+ "properties": {
107
+ "envelope": {
108
+ "type": "string",
109
+ "minLength": 1,
110
+ "description": "URL for envelope submission (POST)"
111
+ },
112
+ "context": {
113
+ "type": "string",
114
+ "minLength": 1,
115
+ "description": "URL for context ledger operations"
116
+ },
117
+ "discovery": {
118
+ "type": "string",
119
+ "minLength": 1,
120
+ "description": "URL of this discovery document"
121
+ }
122
+ },
123
+ "additionalProperties": false
124
+ },
125
+ "extensions": {
126
+ "type": "object",
127
+ "description": "Extension fields for vendor-specific metadata",
128
+ "additionalProperties": true
129
+ }
130
+ },
131
+ "additionalProperties": false
132
+ }
File without changes
File without changes