@jigging/agent-method 0.0.0 → 0.1.0-alpha.4

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 (52) hide show
  1. package/AGENTS.md +98 -0
  2. package/FLOW.contract.json +241 -0
  3. package/FLOW.meta.json +8 -0
  4. package/FLOW.ts +3 -0
  5. package/LICENSE +373 -0
  6. package/README.md +369 -0
  7. package/THIRD_PARTY_NOTICES +9 -0
  8. package/contracts/acp-public-updates.json +75 -0
  9. package/contracts/agent-commands.json +88 -0
  10. package/contracts/agent-replies.json +202 -0
  11. package/contracts/http-request/contract.json +37 -0
  12. package/dist/api.d.ts +11 -0
  13. package/dist/api.js +164 -0
  14. package/dist/conversation.d.ts +68 -0
  15. package/dist/conversation.js +346 -0
  16. package/dist/errors.d.ts +5 -0
  17. package/dist/errors.js +8 -0
  18. package/dist/flow.d.ts +3 -0
  19. package/dist/flow.js +2784 -0
  20. package/dist/index.d.ts +67 -0
  21. package/dist/index.js +220 -0
  22. package/dist/json.d.ts +21 -0
  23. package/dist/json.js +409 -0
  24. package/dist/schema.d.ts +7 -0
  25. package/dist/schema.js +180 -0
  26. package/dist/skills.d.ts +3 -0
  27. package/dist/skills.js +132 -0
  28. package/dist/values.d.ts +11 -0
  29. package/dist/values.js +65 -0
  30. package/justfile +32 -0
  31. package/licenses/flow.LICENSE +202 -0
  32. package/package.json +45 -5
  33. package/settings.schema.json +12 -0
  34. package/skills/answer-check/SKILL.md +5 -0
  35. package/src/api.ts +191 -0
  36. package/src/conversation.ts +387 -0
  37. package/src/errors.ts +11 -0
  38. package/src/flow.ts +66 -0
  39. package/src/index.ts +325 -0
  40. package/src/json.ts +406 -0
  41. package/src/schema.ts +230 -0
  42. package/src/skills.ts +138 -0
  43. package/src/values.ts +77 -0
  44. package/test/api.test.ts +326 -0
  45. package/test/conversation-fixture.ts +73 -0
  46. package/test/conversation.test.ts +328 -0
  47. package/test/json.test.ts +88 -0
  48. package/test/method.test.ts +308 -0
  49. package/test/pack.test.ts +81 -0
  50. package/test/result.test.ts +103 -0
  51. package/test/skills-flow.test.ts +252 -0
  52. package/tsconfig.json +17 -0
package/README.md ADDED
@@ -0,0 +1,369 @@
1
+ # Reusable Agent method
2
+
3
+ `@jigging/agent-method` prepares one bounded Agent request and interprets its
4
+ result. The same implementation is available as a pure library and as an
5
+ ordinary FLOW package. The complete archive contains runnable output, source,
6
+ types, contracts, selected method guidance and licenses, with no runtime npm
7
+ dependencies or installation hooks.
8
+
9
+ This is a source candidate. Build an archive from the revision you reviewed;
10
+ this README does not assert registry publication.
11
+
12
+ ## Choose how to use it
13
+
14
+ | Entry | Guidance source | Invocation |
15
+ | --- | --- | --- |
16
+ | Pure library | Explicit input and Skill text supplied by its caller | In the caller's existing process |
17
+ | Ordinary `FLOW.ts` | Explicit caller Skill contents and guidance | One Run/0 invocation and one granted HTTP request |
18
+ | Ordinary ACP Agent package | The same explicit Skill contents and guidance | Separate Flow using this library and a finite native resource |
19
+
20
+ The ordinary Flow offers the exact Agent Run contract. Its result does not
21
+ attest caller context. A root can call the Agent Flow directly or through a specialist's
22
+ ordinary slot. Each uses its own Binding and grants. The specialist → Agent
23
+ branch reserves both child levels. Two such branches fit Jig's fixed aggregate
24
+ resource budget; a third is rejected rather than queued.
25
+
26
+ Its HTTP implementation declares `supports: []`: it supplies the baseline
27
+ one-shot method without optional Agent events, conversations or sessions. A
28
+ caller with no extra requirements needs no feature declaration. A caller that
29
+ requires those mechanisms can reject this selection during inert review through
30
+ the [Agent feature requirements](https://jig.md/spec/agent-run#declare-required-agent-behavior).
31
+
32
+ ## Pure library
33
+
34
+ ```ts
35
+ import { prepareAgent, finishAgent } from '@jigging/agent-method'
36
+
37
+ const prepared = prepareAgent({
38
+ instructions: 'Summarize this observation.',
39
+ guidance: [{ label: 'observation', text: 'The second measurement was lower.' }],
40
+ })
41
+
42
+ // Your implementation supplies bounded transport facts.
43
+ const response = await yourTransport(prepared.request)
44
+ const result = finishAgent(prepared, response)
45
+ ```
46
+
47
+ `yourTransport` is application code, not an implicit Jig service. This package's
48
+ HTTP implementation and `@jigging/agent-acp` show concrete granted transports.
49
+ Your host supplies authorized execution. Neither library function calls a
50
+ provider, reads files, chooses credentials or grants authority.
51
+
52
+ Public exports are:
53
+
54
+ ```ts
55
+ prepareAgent(input: AgentInput, selectedSkills?: readonly SkillText[]): PreparedAgent
56
+ finishAgent(prepared: PreparedAgent, result: unknown): AgentResult
57
+ checkAgentResult(result: unknown, responseSchema?: JsonObject): AgentResult
58
+ assertResponseSchema(schema: JsonObject): void
59
+ projectResponseSchema(schema: JsonObject): JsonObject
60
+ ```
61
+
62
+ The package also exports `AgentMethodError`, `AgentMethodErrorCode`, and the
63
+ `AgentInput`, `AgentCallInput`, `AgentSessionRequest`, `AgentSessionReceipt`,
64
+ `SkillText`, `PreparedAgent`, `AgentResult`, `AgentTransportInput`,
65
+ `AgentTransportResult`, `JsonObject`, and `JsonValue` types.
66
+
67
+ `AgentInput` is
68
+ `{ instructions, guidance?: [{ label, text }], responseSchema?, session? }`.
69
+ `AgentSessionRequest` is `{ retain: true, lifetime?: 'run' } | { restore: string }`,
70
+ with an opaque UUID reference for restoration. `lifetime: 'run'` bounds state to
71
+ the active root Run; restoring inherits that lifetime. Omission permits the
72
+ existing cross-Run retention. It requests native state handling from a
73
+ compatible implementation under its current grant; it confers no authority.
74
+ Selected `SkillText` values are `{ name, files: [{ path, text }] }`; every Skill
75
+ requires `SKILL.md`. Names use lowercase letters, digits and separating hyphens,
76
+ up to 64 characters. Paths are relative to the selected Skill, with no empty,
77
+ `.` or `..` components, backslashes or NULs.
78
+
79
+ Preparation snapshots the input and returns frozen ordinary data:
80
+ `{ request: { prompt, responseSchema? }, session? }`. Session metadata remains
81
+ outside `request` and is never rendered into the prompt. The data can be
82
+ inspected, serialized, cloned and adapted; finishing validates it again. It is
83
+ not an authorization token. `projectResponseSchema` returns a fresh copy with only
84
+ the root FLOW `$schema` removed for a provider's structured-output API.
85
+
86
+ The transport supplies `{ outcome: 'done', output: { text, stop } }`, where `stop`
87
+ is `end-turn`, `refusal` or `limit`. Finishing returns
88
+ `{ outcome: 'done' | 'blocked' | 'limit', output: { text, structured? } }`.
89
+ With a response schema, a completed answer must contain valid matching JSON.
90
+ One complete `json` Markdown fence is accepted, as is raw JSON; surrounding
91
+ prose, duplicate members and malformed JSON reject. For blocked or limited
92
+ answers, non-JSON text is retained without `structured`. If such an answer
93
+ does contain JSON, that value must still match the requested schema.
94
+
95
+ `finishAgent` returns only the interpreted answer; it never manufactures a
96
+ session receipt. A selected native Agent Flow can add `output.session` after
97
+ its resource settles. `AgentSessionReceipt` is
98
+ `{ status: 'retained', reference: string } | { status: 'unavailable', reason }`.
99
+ The closed reasons are `not-cleanly-closed`, `missing-history`, `unsupported-history`
100
+ and `capacity`; they describe retention, not answer quality.
101
+ `checkAgentResult` validates that optional receipt's closed shape and UUID
102
+ alongside the answer, but does not access storage or establish host authority.
103
+
104
+ Invalid inputs and prepared values throw `AgentMethodError('INVALID_INPUT')`;
105
+ explicit method bounds use `RESOURCE_EXHAUSTED`; invalid transport facts or
106
+ structured answers use `INVALID_RESULT`. Operational transport failures remain
107
+ failures and are never converted to a domain outcome or retried.
108
+
109
+ ## Conversation caller
110
+
111
+ The optional `@jigging/agent-method/conversation` export manages a continuing
112
+ Agent call using the public FLOW SDK and Agent Run contract. It works with a
113
+ compatible selected Agent; the HTTP implementation in this package remains
114
+ one-shot. It introduces no host service or additional authority.
115
+
116
+ ```ts
117
+ import { withAgentConversation } from '@jigging/agent-method/conversation'
118
+
119
+ const completed = await withAgentConversation(run, {
120
+ operationId: 'incident-brief', slot: 'agent',
121
+ input: { instructions: 'Draft a brief from the supplied incident facts.' },
122
+ onEvent(event) {
123
+ if (event.sessionUpdate === 'agent_message_chunk') console.log(event.content.text)
124
+ },
125
+ }, async conversation => {
126
+ const draft = await conversation.initial
127
+ if (draft.type !== 'result' || draft.result.outcome !== 'done') return draft
128
+ return await conversation.prompt({ instructions: 'Revise: the outage lasted 48 minutes.' })
129
+ })
130
+ ```
131
+
132
+ The caller declares the exact Agent bundle and required mechanisms once in
133
+ `FLOW.meta.json`. The helper resolves channel agreements through that slot:
134
+
135
+ With Jig, import the installed bundle in one step into an existing `contracts/`
136
+ parent: `jig import-contract node_modules/@jigging/agent-method/FLOW.contract.json flows/worker/contracts/agent-run`.
137
+ This copies the validated offline closure without running code or granting authority.
138
+
139
+ ```json
140
+ {
141
+ "uses": {
142
+ "agent": {
143
+ "contract": "./contracts/agent-run/FLOW.contract.json",
144
+ "requires": ["conversation", "events"]
145
+ }
146
+ }
147
+ }
148
+ ```
149
+
150
+ `events` is needed here because the example supplies `onEvent`; a conversation
151
+ without observation needs only `conversation`. Declarations check the selected
152
+ implementation's claims before the caller starts. They do not grant a second
153
+ prompt or promise successful work. The result contains the callback's `value`, all
154
+ received `turns`, and the actual invocation `settlement`. The helper closes the
155
+ settled conversation and awaits owned invocation completion before returning.
156
+ It does not judge answer quality. `initial` and `prompt()` resolve to a
157
+ `result`, `cancelled`, or `error` turn; domain outcomes remain explicit data.
158
+
159
+ To request native retention or restoration, supply `session` in the initial
160
+ `input`. Its receipt appears only in `completed.settlement.output.session`,
161
+ after resource settlement, never in `turns`. Follow-up
162
+ `prompt(input: Omit<AgentInput, 'session'>)` supplies new instructions, optional
163
+ guidance and a response schema; it cannot change the invocation's session
164
+ request. The selected implementation and reviewed native grant must support it.
165
+
166
+ `interrupt()` resolves to `accepted` or `not-running`; await the active turn to
167
+ learn whether native cancellation or ordinary completion won. Concurrent prompts
168
+ are rejected, never queued. A callback that leaves a live turn unfinished fails
169
+ and closes its command channel; the helper still waits for the invocation's
170
+ actual settlement. It never cancels that local waiter to manufacture cleanup.
171
+ Root cancellation remains fatal to the Run.
172
+
173
+ Optional `onEvent` handles synchronous filtering and presentation of public
174
+ updates; the helper owns its channel and disposal. It returns
175
+ `observation: {status: 'complete'}` or `{status: 'incomplete', errors}` separately
176
+ from actual conversation settlement. A failed display or lagged stream does not
177
+ turn successful work into failed execution. For asynchronous processing or
178
+ forwarding, supply the lower-level `events` writer instead; these alternatives
179
+ cannot be combined. An async `onEvent` is rejected as incomplete observation,
180
+ not awaited as part of Agent execution. One-shot callers still use `run.call()`.
181
+
182
+ `AgentConversationError` retains `turns`, any known `settlement`, and primary
183
+ and cleanup `errors`. Catch it normally to retain partial work, not to infer
184
+ successful cleanup from a missing settlement. Optional `events` accepts a
185
+ caller-created update writer; filtering and presentation remain caller-owned.
186
+ See the [conversation guide](https://jig.md/guide/conversations) for grants,
187
+ control semantics, and the raw channel interface.
188
+
189
+ ## Ordinary Flow and explicit Skills
190
+
191
+ The root `FLOW.ts` runs the bundled method through Run/0. Its input adds
192
+ `skills?: SkillText[]` to the shared input. This HTTP implementation rejects any
193
+ `session` field, conversational mode and requested channels before HTTP
194
+ dispatch. Omitted Skills supply none. For example:
195
+
196
+ ```json
197
+ {
198
+ "instructions": "Explain a way to check an assumption.",
199
+ "skills": [{ "name": "answer-check", "files": [{ "path": "SKILL.md", "text": "Check the answer against supplied evidence." }] }]
200
+ }
201
+ ```
202
+
203
+ Names and paths describe explicit data; they do not cause host file reads or
204
+ attest provenance. The optional reader below loads selected package-local
205
+ trees. The included `answer-check` Skill is a small editable example. Model
206
+ choice belongs in reviewed Binding settings.
207
+
208
+ An ordinary caller should pass the requested schema to `checkAgentResult`
209
+ before relying on a replacement's structured result. This pure check validates
210
+ the result envelope and dynamic data; it cannot establish semantic correctness.
211
+
212
+ For a package extracted at `flows/agent`, configure one Binding:
213
+
214
+ ```ts
215
+ import { defineBinding } from '@jigging/jig'
216
+
217
+ export default defineBinding({
218
+ package: 'flows/agent',
219
+ settings: { model: 'your-model', maxCompletionTokens: 4096 },
220
+ slots: {
221
+ http: {
222
+ kind: 'http',
223
+ url: 'https://api.openai.com/v1/chat/completions',
224
+ method: 'POST',
225
+ bearerEnv: 'OPENAI_API_KEY',
226
+ },
227
+ },
228
+ })
229
+ ```
230
+
231
+ Name it `bindings/agent.ts`, include that Binding and Flow in `jig.ts`, then
232
+ `jig review` and `jig run binding:agent --input @task.json`. The operator supplies
233
+ the named credential through their environment. The Flow receives neither its
234
+ value nor network access. This path needs no native Agent configuration.
235
+ `settings.schema.json` requires a nonempty model; `maxCompletionTokens` defaults
236
+ to 4096 and accepts 1–65536. A grant's optional `bodySchema` can enforce model and
237
+ token restrictions outside the method; settings alone do not constrain malicious
238
+ code. Review the exact endpoint and its data policy before granting access.
239
+
240
+ Extract the complete archive into a real project directory, then add that
241
+ directory using ordinary Flow membership. An explicit installed real directory
242
+ can also be used where the host accepts it; package-manager symlinks still
243
+ receive that host's ordinary symlink rules. Running the packed `FLOW.ts` needs
244
+ no consumer build or registry dependency resolution.
245
+
246
+ This Flow makes one non-streaming text-only request using the configured API.
247
+ The exact endpoint remains in the HTTP grant; `api` changes only the request
248
+ and response format, never the destination or permissions.
249
+
250
+ | Setting | Values and default | Meaning |
251
+ | --- | --- | --- |
252
+ | `api` | `chat-completions` (default), `responses` | Select the wire API matching the granted endpoint. |
253
+ | `structuredOutput` | `prompt` (default), `json-schema` | Request a supplied `responseSchema` through prompt guidance alone or through the provider's strict schema format as well. |
254
+ | `maxCompletionTokens` | 1–65536; default 4096 | Bound generated tokens using the selected API's token field. |
255
+
256
+ [Chat Completions](https://developers.openai.com/api/reference/resources/chat/subresources/completions/methods/create)
257
+ uses `max_completion_tokens`, one choice, and optional `response_format.json_schema`.
258
+ Responses uses `max_output_tokens` and optional `text.format`; both strict schema
259
+ forms set `strict: true`. Those are the provider's
260
+ [structured-output formats](https://developers.openai.com/api/docs/guides/structured-outputs).
261
+ For example, select a Responses endpoint and strict output in the same Binding:
262
+
263
+ ```ts
264
+ settings: { model: 'your-model', api: 'responses', structuredOutput: 'json-schema' },
265
+ slots: {
266
+ http: {
267
+ kind: 'http', method: 'POST',
268
+ url: 'https://api.openai.com/v1/responses', bearerEnv: 'OPENAI_API_KEY',
269
+ },
270
+ },
271
+ ```
272
+
273
+ Both APIs request `store: false`, omit tools, and validate structured answers
274
+ locally. Strict output requires support from the selected endpoint and model;
275
+ rejection is a failure, never a retry in prompt mode. Without a supplied
276
+ `responseSchema`, either setting requests ordinary text. Settings guide the
277
+ method; the grant enforces any required body restrictions.
278
+
279
+ Only settled responses are accepted. Chat requires one complete choice;
280
+ Responses accepts assistant text/refusals and ignores reasoning metadata.
281
+ Tool requests, asynchronous or failed responses, unknown termination reasons,
282
+ malformed replies and non-200 HTTP statuses fail without echoing provider error
283
+ bodies. Refusal and explicit token exhaustion remain `blocked` and `limit`
284
+ outcomes. No request is retried, including after cancellation or uncertain dispatch.
285
+
286
+ The exact Agent Run contract declares optional updates. This HTTP implementation
287
+ rejects a requested channel before dispatch; it supplies no streaming or ACP
288
+ updates. Native clients remain available for those features.
289
+ HTTP grants default to a 256 KiB canonical request and 1 MiB response. Larger
290
+ requests and answers require explicit `requestBytes` / `responseBytes` policy,
291
+ up to 8 MiB / 12 MiB. The Flow requests `response: 'json'` and interprets the
292
+ decoded API value, avoiding an extra JSON-string wrapper around large answers.
293
+ The shared 1 MiB rendered prompt, 8 MiB answer text and JSON/0 complete-value
294
+ bounds remain unchanged. Each request stays within the grant's timeout (at most
295
+ 60 seconds) and enclosing deadline. Oversized values fail rather than being
296
+ clipped. Caller-supplied context is not host-attested provenance.
297
+
298
+ The separate filesystem export is:
299
+
300
+ ```ts
301
+ import { readPackageSkills } from '@jigging/agent-method/skills'
302
+
303
+ const selected = await readPackageSkills(new URL('./', import.meta.url), ['answer-check'])
304
+ ```
305
+
306
+ Place that literal URL in the caller's package-root module; the reader never infers a root
307
+ from `dist/` or the process working directory. Supply a `file:` directory URL
308
+ ending with `/`. Selected trees must contain only real directories and regular
309
+ UTF-8 files, with no symlinks anywhere in their directory paths. Reads check
310
+ file identity and size; callers should supply an immutable package. This is a
311
+ bounded source reader, not an authenticated filesystem or admission boundary.
312
+ Traversal is bounded to 4,096 entries and 4,096 bytes per relative file path.
313
+
314
+ ## Bounds and structured output
315
+
316
+ Selected Skills sort by unsigned UTF-8 bytes, as do their file paths. Duplicate
317
+ Skill names or paths reject. Plain guidance preserves its explicit sequence
318
+ and requires unique nonempty labels. Labels occupy a separate namespace from
319
+ Skills and are ordinary data, not provenance or permission.
320
+
321
+ Skills plus guidance share 64 groups and 1,024 files/text items. Their UTF-8
322
+ content plus instructions is bounded to 1 MiB. The rendered prompt, including
323
+ JSON escaping, labels, paths and schema instructions, has a separate 1 MiB
324
+ bound. Oversized content is rejected rather than truncated.
325
+
326
+ The schema profile requires the root declaration
327
+ `https://flow.jig.md/schemas/schema-0.json` and a nonempty closed object with
328
+ every property required. Nested nodes support closed objects, bounded arrays,
329
+ strings and safe integers; only string/integer nodes can be nullable. String
330
+ enums are supported. Booleans, numbers, references, optional properties and
331
+ open objects are outside this deliberate profile. Optional descriptions are
332
+ accepted. Limits are 256 KiB canonical schema bytes, depth 8, 32 properties per
333
+ object, 128 total properties, 256 array items, 256 total enum values and 120,000
334
+ property-name/enum Unicode scalar values. Enums with over 250 values are limited
335
+ to 15,000 string scalar values. Nullable string enums contain both null and at
336
+ least one string. JSON/0's finite safe-number, Unicode, duplicate-member and
337
+ absolute value bounds apply throughout.
338
+
339
+ ## Build and adapt
340
+
341
+ In the repository, install workspace dependencies at the root, build the FLOW
342
+ SDK first (`just flow::build`), then run `just agent::build`. The package recipe
343
+ builds only this package. Supported development inputs are Bun 1.3.3,
344
+ TypeScript 7.0.2, Node types 24.13.3 and Just 1.43.1 or newer.
345
+
346
+ To adapt extracted source, run `bun install --ignore-scripts`, then `just build`.
347
+ Bun packs workspace references as ordinary versioned development dependencies.
348
+ Retain the generated Bun lock for reproducible local development. The packed
349
+ library and runtime use Node-compatible ESM and need no development installation.
350
+
351
+ Change `src/index.ts` for prompt preparation or interpretation,
352
+ `src/schema.ts` for schema checking, or `skills/` for package guidance.
353
+ Run `just test`, then `just pack --destination <directory>`. Review and adopt
354
+ the complete artifact under your host's normal source rules. The rebuilt
355
+ `dist/flow.js` is what the root entrypoint executes.
356
+
357
+ The pack recipe builds first and calls Bun's ordinary packer. To pack existing
358
+ output, use `bun pm pack --ignore-scripts --destination <directory>`. Neither
359
+ path publishes, mutates source manifests or embeds dependency archives.
360
+ Rebuilding extracted source requires its declared dependency versions to be
361
+ available; unpublished development uses ordinary source workspaces.
362
+
363
+ Tests cover preparation/results, JSON/0 bounds, package reads, ordinary Flow
364
+ wiring, source inclusion, dependency versions and standalone runtime imports.
365
+ They do not establish provider quality, real-client compatibility or containment.
366
+
367
+ MPL-2.0 covers this package and its adapted Jig algorithms. The bundled FLOW
368
+ SDK is Apache-2.0; see `LICENSE`, `THIRD_PARTY_NOTICES` and
369
+ `licenses/flow.LICENSE` for the corresponding notices.
@@ -0,0 +1,9 @@
1
+ @jigging/agent-method is distributed under the Mozilla Public License 2.0.
2
+ The bounded JSON/0 codec, schema profile, instruction presentation and result
3
+ algorithms are adapted from Jig. Their source is included in src/.
4
+
5
+ The complete dist/flow.js runtime bundles @jigging/flow, the FLOW Run/0 SDK,
6
+ under the Apache License 2.0. Its license is included in licenses/flow.LICENSE.
7
+ SDK source is available from https://github.com/jiggy/jig/tree/main/packages/flow-sdk.
8
+
9
+ No provider SDK is included in this package.
@@ -0,0 +1,75 @@
1
+ {
2
+ "$schema": "https://flow.jig.md/schemas/channel-contract-0.schema.json",
3
+ "id": "https://jig.md/contracts/acp-public-updates",
4
+ "version": "0.1.0",
5
+ "semantics": "A bounded projection of an ACP Agent invocation. agent_message_chunk items append public assistant text in received order; an optional messageId identifies the source message, not an invocation. plan items replace the complete current plan. Only text content and plan entries are projected. Thoughts, tools, permissions, credentials and raw ACP messages are excluded. Delivery may fail independently of the Agent result. End of this sequence is not proof that the Agent succeeded. No replay or session control is provided. Conversational calls add turn (0–7) to every item; one-shot calls omit it. Turn identity is application correlation, not authority or proof of native causal ordering.",
6
+ "item": {
7
+ "oneOf": [
8
+ {
9
+ "type": "object",
10
+ "properties": {
11
+ "sessionUpdate": {
12
+ "const": "agent_message_chunk"
13
+ },
14
+ "content": {
15
+ "type": "object",
16
+ "properties": {
17
+ "type": {
18
+ "const": "text"
19
+ },
20
+ "text": {
21
+ "type": "string"
22
+ }
23
+ },
24
+ "required": ["type", "text"],
25
+ "additionalProperties": false
26
+ },
27
+ "messageId": {
28
+ "type": "string"
29
+ },
30
+ "turn": {
31
+ "type": "integer",
32
+ "minimum": 0,
33
+ "maximum": 7
34
+ }
35
+ },
36
+ "required": ["sessionUpdate", "content"],
37
+ "additionalProperties": false
38
+ },
39
+ {
40
+ "type": "object",
41
+ "properties": {
42
+ "sessionUpdate": {
43
+ "const": "plan"
44
+ },
45
+ "entries": {
46
+ "type": "array",
47
+ "items": {
48
+ "type": "object",
49
+ "properties": {
50
+ "content": {
51
+ "type": "string"
52
+ },
53
+ "priority": {
54
+ "enum": ["high", "medium", "low"]
55
+ },
56
+ "status": {
57
+ "enum": ["pending", "in_progress", "completed"]
58
+ }
59
+ },
60
+ "required": ["content", "priority", "status"],
61
+ "additionalProperties": false
62
+ }
63
+ },
64
+ "turn": {
65
+ "type": "integer",
66
+ "minimum": 0,
67
+ "maximum": 7
68
+ }
69
+ },
70
+ "required": ["sessionUpdate", "entries"],
71
+ "additionalProperties": false
72
+ }
73
+ ]
74
+ }
75
+ }
@@ -0,0 +1,88 @@
1
+ {
2
+ "$schema": "https://flow.jig.md/schemas/channel-contract-0.schema.json",
3
+ "id": "https://jig.md/contracts/agent-commands",
4
+ "version": "0.1.0",
5
+ "semantics": "Direct controls for an explicitly conversational Agent Run. Initial invocation input starts turn 0. Prompt names the next sequential turn; interrupt names the running turn; close names the last settled turn. Controls are accepted or rejected separately from turn settlement and final invocation cleanup. Delivery is not dispatch or completion. No automatic queue or replay.",
6
+ "item": {
7
+ "oneOf": [
8
+ {
9
+ "type": "object",
10
+ "properties": {
11
+ "type": {
12
+ "const": "prompt"
13
+ },
14
+ "turn": {
15
+ "type": "integer",
16
+ "minimum": 0,
17
+ "maximum": 7
18
+ },
19
+ "input": {
20
+ "type": "object",
21
+ "properties": {
22
+ "instructions": {
23
+ "type": "string",
24
+ "minLength": 1,
25
+ "maxLength": 1048576
26
+ },
27
+ "responseSchema": {
28
+ "type": "object"
29
+ },
30
+ "guidance": {
31
+ "type": "array",
32
+ "maxItems": 64,
33
+ "items": {
34
+ "type": "object",
35
+ "properties": {
36
+ "label": {
37
+ "type": "string",
38
+ "minLength": 1
39
+ },
40
+ "text": {
41
+ "type": "string"
42
+ }
43
+ },
44
+ "required": [
45
+ "label",
46
+ "text"
47
+ ],
48
+ "additionalProperties": false
49
+ }
50
+ }
51
+ },
52
+ "required": [
53
+ "instructions"
54
+ ],
55
+ "additionalProperties": false
56
+ }
57
+ },
58
+ "required": [
59
+ "type",
60
+ "turn",
61
+ "input"
62
+ ],
63
+ "additionalProperties": false
64
+ },
65
+ {
66
+ "type": "object",
67
+ "properties": {
68
+ "type": {
69
+ "enum": [
70
+ "interrupt",
71
+ "close"
72
+ ]
73
+ },
74
+ "turn": {
75
+ "type": "integer",
76
+ "minimum": 0,
77
+ "maximum": 7
78
+ }
79
+ },
80
+ "required": [
81
+ "type",
82
+ "turn"
83
+ ],
84
+ "additionalProperties": false
85
+ }
86
+ ]
87
+ }
88
+ }