@x-otto/orchestration-contracts 0.0.1-alpha.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 ADDED
@@ -0,0 +1,72 @@
1
+ # @x-otto/orchestration-contracts
2
+
3
+ > orchestrator↔tools pure type contracts. Zero runtime — `export type` only, compiled output is empty.
4
+
5
+ `@x-otto/orchestration-contracts` defines the callback port types between the orchestrator execution kernel (`@x-otto/orchestrator`) and the tools adapter layer (`@x-otto/tools`). It provides `TaskStatus`, `Result<T>`, `TodoItem`, 8 callback function signatures (TaskDispatch, CallAgent, WriteTodos, etc.), and the MODEL_SLOTS constant. Both sides `import type`, avoiding a circular dependency.
6
+
7
+ ## Installation
8
+
9
+ ```bash
10
+ pnpm add @x-otto/orchestration-contracts
11
+ ```
12
+
13
+ ## Usage
14
+
15
+ ```ts
16
+ import type {
17
+ TaskStatus,
18
+ Result,
19
+ TodoItem,
20
+ TaskDispatch,
21
+ CallAgent,
22
+ WriteTodos,
23
+ } from '@x-otto/orchestration-contracts'
24
+ import { MODEL_SLOTS } from '@x-otto/orchestration-contracts'
25
+
26
+ // Result<T> discriminant union
27
+ function handleResult<T>(result: Result<T>) {
28
+ if (result.ok) {
29
+ console.log('Success:', result.value)
30
+ } else {
31
+ console.error('Error:', result.error)
32
+ }
33
+ }
34
+
35
+ // Task status
36
+ const status: TaskStatus = 'running' // 'pending' | 'running' | 'completed' | 'failed' | 'cancelled'
37
+ ```
38
+
39
+ ## API
40
+
41
+ ### Primitives
42
+ - `Result<T>` — `{ ok: true; value: T } | { ok: false; error: string }`
43
+ - `TaskStatus` — `'pending' | 'running' | 'completed' | 'failed' | 'cancelled'`
44
+ - `ModelSlotName` — `'normal' | 'thinking' | 'compact' | 'critique' | 'vision'`
45
+ - `SessionMode` — `'ephemeral' | 'sticky'`
46
+ - `TaskMode` — `'sync' | 'background'`
47
+ - `TodoStatus` / `TodoItem` — todo list types
48
+ - `MODEL_SLOTS` — constant array of 5 slot names
49
+
50
+ ### Callback Ports
51
+ - `TaskDispatch` — delegate task (sync/background)
52
+ - `CallAgent` — synchronous isolated agent call
53
+ - `GetTask` / `GetTaskData` — task querying
54
+ - `ListTasks` — list tasks by status
55
+ - `UpdateTask` — cancel/retry a task
56
+ - `GetBackgroundOutput` — read background task output
57
+ - `CancelBackground` — cancel background task
58
+ - `WriteTodos` — write todo list
59
+ - `WorkflowOptions` — delegation depth, max retries, etc.
60
+
61
+ ### Utilities
62
+ - `checkDelegationDepth(args, maxDepth)` — delegation depth guard
63
+ - `createTodoStore()` — lightweight in-memory todo store
64
+
65
+ ## Dependencies
66
+
67
+ - Internal: `@x-otto/interchange` (type-only)
68
+ - External: none
69
+
70
+ ## Related
71
+
72
+ - [Architecture](./ARCHITECTURE.md)
@@ -0,0 +1,115 @@
1
+ import { TodoItem, TodoStatus } from "@x-otto/interchange";
2
+
3
+ //#region src/primitives.d.ts
4
+ type TaskStatus = 'pending' | 'running' | 'completed' | 'failed' | 'cancelled';
5
+ /** 模型槽位词表(单一真源)——`ai.WORKFLOW_SLOTS` 从此派生、`setting` 直取,消 split-brain。 */
6
+ declare const MODEL_SLOTS: readonly ["normal", "thinking", "compact", "critique", "vision"];
7
+ type ModelSlotName = (typeof MODEL_SLOTS)[number];
8
+ type SessionMode = 'ephemeral' | 'sticky';
9
+ type TaskMode = 'sync' | 'background';
10
+ /**
11
+ * 领域结果判别联合(RFC-004 D36 §4-15)。
12
+ * 跨包契约不再泄漏 `{success,output,error}` UI 软字典:成功携领域值 `value`,失败携人读 `error`。
13
+ * 软字典只允许出现在面向 LLM 的 tools 适配层(把 Result 投影为 ToolResult 文案/isError)。
14
+ */
15
+ type Result<T> = {
16
+ ok: true;
17
+ value: T;
18
+ } | {
19
+ ok: false;
20
+ error: string;
21
+ };
22
+ interface DispatchOutcome {
23
+ id: string;
24
+ status: TaskStatus;
25
+ output?: string;
26
+ }
27
+ interface TaskBrief {
28
+ id: string;
29
+ prompt: string;
30
+ status: TaskStatus;
31
+ }
32
+ interface BackgroundOutput {
33
+ status: TaskStatus;
34
+ output?: string;
35
+ }
36
+ /** 编排工作流配置(M-B3 单源——consumed by orchestrator & setting)。 */
37
+ interface WorkflowOptions {
38
+ retry?: {
39
+ enabled?: boolean;
40
+ maxAttempts?: number;
41
+ };
42
+ circuitBreaker?: {
43
+ enabled?: boolean;
44
+ failureThreshold?: number;
45
+ timeoutMs?: number;
46
+ };
47
+ }
48
+ //#endregion
49
+ //#region src/callbacks.d.ts
50
+ type TaskDispatch = (args: {
51
+ prompt: string;
52
+ subagent?: string;
53
+ category?: string;
54
+ mode: TaskMode;
55
+ sessionId?: string;
56
+ sessionMode?: SessionMode;
57
+ slot?: ModelSlotName; /** 显式模型 id(subagent 按能力选型)——优先于 slot。 */
58
+ model?: string; /** 调用方(caller)委托深度(root=0);orchestrator 据此算 childDepth 护栏。 */
59
+ depth?: number; /** 父工具的 AbortSignal——abort 主会话时串联中断 in-flight 子会话(sync 路径;background 故意不串)。 */
60
+ signal?: AbortSignal;
61
+ }) => Promise<Result<DispatchOutcome>>;
62
+ type CallAgent = (agent: string, prompt: string, /** signal 为父工具 AbortSignal——abort 主会话时串联中断 in-flight 子会话。 */
63
+
64
+ options?: {
65
+ slot?: ModelSlotName;
66
+ model?: string;
67
+ depth?: number;
68
+ signal?: AbortSignal;
69
+ }) => Promise<Result<string>>;
70
+ type GetTaskData = {
71
+ id: string;
72
+ status: TaskStatus;
73
+ prompt?: string;
74
+ output?: string;
75
+ error?: string;
76
+ };
77
+ type GetTask = (id: string) => Promise<Result<GetTaskData>>;
78
+ type ListTasks = (status?: TaskStatus | 'all') => Promise<Result<TaskBrief[]>>;
79
+ type UpdateTask = (id: string, action: 'cancel' | 'retry') => Promise<Result<string>>;
80
+ type GetBackgroundOutput = (id: string) => Promise<Result<BackgroundOutput>>;
81
+ type CancelBackground = (id: string) => Promise<Result<void>>;
82
+ /** 写入 Todo 列表 — 对齐 write_todos 工具。成功携合并后的 todo 列表。 */
83
+ type WriteTodos = (args: {
84
+ title?: string;
85
+ action: 'set' | 'update';
86
+ todos: TodoItem[];
87
+ sessionId?: string;
88
+ }) => Promise<Result<TodoItem[]>>;
89
+ //#endregion
90
+ //#region src/delegation.d.ts
91
+ /**
92
+ * 委派深度护栏单源(RFC-057 M90-01 / §6 规则 5 / §10 C14)。
93
+ *
94
+ * `childDepth = (depth ?? 0) + 1`;`exceeded = childDepth > max`。
95
+ * 三处调用点共用,消字节级重复:
96
+ * - orchestrator `dispatchTask`(task_delegate sync/background)
97
+ * - orchestrator `callAgent`(agent_call 轻量旁路)
98
+ * - tools `fork_call`(字节继承旁路)
99
+ *
100
+ * 注意(§10 C14):本轴是「跨委派深度」(一个 agent 能向子 agent 委派多少层,默认 max=1),
101
+ * 与 swarm `MAX_NESTING_DEPTH=5`(team 内部嵌套递归轴)是**同名不同概念**,不得并入。
102
+ */
103
+ interface DelegationDepthCheck {
104
+ /** 子委派的深度(父 depth + 1),传给被委派会话。 */
105
+ childDepth: number;
106
+ /** childDepth 是否越过 max(越过则应拒绝委派)。 */
107
+ exceeded: boolean;
108
+ }
109
+ declare function checkDelegationDepth(depth: number | undefined, max: number): DelegationDepthCheck;
110
+ //#endregion
111
+ //#region src/todo-store.d.ts
112
+ declare function createTodoStore(): WriteTodos;
113
+ //#endregion
114
+ export { type BackgroundOutput, type CallAgent, type CancelBackground, type DelegationDepthCheck, type DispatchOutcome, type GetBackgroundOutput, type GetTask, type GetTaskData, type ListTasks, MODEL_SLOTS, type ModelSlotName, type Result, type SessionMode, type TaskBrief, type TaskDispatch, type TaskMode, type TaskStatus, type TodoItem, type TodoStatus, type UpdateTask, type WorkflowOptions, type WriteTodos, checkDelegationDepth, createTodoStore };
115
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../src/primitives.ts","../src/callbacks.ts","../src/delegation.ts","../src/todo-store.ts"],"mappings":";;;KAEY,UAAA;;cAGC,WAAA;AAAA,KACD,aAAA,WAAwB,WAAA;AAAA,KAExB,WAAA;AAAA,KAEA,QAAA;;AALZ;;;;KAYY,MAAA;EAAc,EAAA;EAAU,KAAA,EAAO,CAAA;AAAA;EAAQ,EAAA;EAAW,KAAA;AAAA;AAAA,UAE7C,eAAA;EACf,EAAA;EACA,MAAA,EAAQ,UAAA;EACR,MAAA;AAAA;AAAA,UAGe,SAAA;EACf,EAAA;EACA,MAAA;EACA,MAAA,EAAQ,UAAA;AAAA;AAAA,UAGO,gBAAA;EACf,MAAA,EAAQ,UAAA;EACR,MAAA;AAAA;;UAIe,eAAA;EACf,KAAA;IAAU,OAAA;IAAmB,WAAA;EAAA;EAC7B,cAAA;IAAmB,OAAA;IAAmB,gBAAA;IAA2B,SAAA;EAAA;AAAA;;;KC3BvD,YAAA,IAAgB,IAAA;EAC1B,MAAA;EACA,QAAA;EACA,QAAA;EACA,IAAA,EAAM,QAAA;EACN,SAAA;EACA,WAAA,GAAc,WAAA;EACd,IAAA,GAAO,aAAA,EDdkF;ECgBzF,KAAA,WDhByF;ECkBzF,KAAA,WDjBU;ECmBV,MAAA,GAAS,WAAA;AAAA,MACL,OAAA,CAAQ,MAAA,CAAO,eAAA;AAAA,KAET,SAAA,IACV,KAAA,UACA,MAAA;;AAEA,OAAA;EAAY,IAAA,GAAO,aAAA;EAAe,KAAA;EAAgB,KAAA;EAAgB,MAAA,GAAS,WAAA;AAAA,MACxE,OAAA,CAAQ,MAAA;AAAA,KAED,WAAA;EACV,EAAA;EACA,MAAA,EAAQ,UAAA;EACR,MAAA;EACA,MAAA;EACA,KAAA;AAAA;AAAA,KAGU,OAAA,IAAW,EAAA,aAAe,OAAA,CAAQ,MAAA,CAAO,WAAA;AAAA,KAEzC,SAAA,IAAa,MAAA,GAAS,UAAA,aAAuB,OAAA,CAAQ,MAAA,CAAO,SAAA;AAAA,KAE5D,UAAA,IAAc,EAAA,UAAY,MAAA,yBAA+B,OAAA,CAAQ,MAAA;AAAA,KAEjE,mBAAA,IAAuB,EAAA,aAAe,OAAA,CAAQ,MAAA,CAAO,gBAAA;AAAA,KAErD,gBAAA,IAAoB,EAAA,aAAe,OAAA,CAAQ,MAAA;;KAG3C,UAAA,IAAc,IAAA;EACxB,KAAA;EACA,MAAA;EACA,KAAA,EAAO,QAAA;EACP,SAAA;AAAA,MACI,OAAA,CAAQ,MAAA,CAAO,QAAA;;;;;;ADzDrB;;;;;AAGA;;;;UEOiB,oBAAA;EFNL;EEQV,UAAA;;EAEA,QAAA;AAAA;AAAA,iBAGc,oBAAA,CAAqB,KAAA,sBAA2B,GAAA,WAAc,oBAAA;;;iBCd9D,eAAA,CAAA,GAAmB,UAAA"}
package/dist/index.js ADDED
@@ -0,0 +1,2 @@
1
+ const e=[`normal`,`thinking`,`compact`,`critique`,`vision`];function t(e,t){let n=(e??0)+1;return{childDepth:n,exceeded:n>t}}function n(){let e=new Map;return async({action:t,todos:n,sessionId:r})=>{let i=r?.trim()||`__default__`,a=e.get(i)??[];if(t===`set`)a=[...n];else{let e=new Map(a.map(e=>[e.id,e]));for(let t of n)e.set(t.id,t);a=[...e.values()]}return e.set(i,a),{ok:!0,value:a}}}export{e as MODEL_SLOTS,t as checkDelegationDepth,n as createTodoStore};
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":[],"sources":["../src/primitives.ts","../src/delegation.ts","../src/todo-store.ts"],"sourcesContent":["export type { TodoStatus, TodoItem } from '@x-otto/interchange'\n\nexport type TaskStatus = 'pending' | 'running' | 'completed' | 'failed' | 'cancelled'\n\n/** 模型槽位词表(单一真源)——`ai.WORKFLOW_SLOTS` 从此派生、`setting` 直取,消 split-brain。 */\nexport const MODEL_SLOTS = ['normal', 'thinking', 'compact', 'critique', 'vision'] as const\nexport type ModelSlotName = (typeof MODEL_SLOTS)[number]\n\nexport type SessionMode = 'ephemeral' | 'sticky'\n\nexport type TaskMode = 'sync' | 'background'\n\n/**\n * 领域结果判别联合(RFC-004 D36 §4-15)。\n * 跨包契约不再泄漏 `{success,output,error}` UI 软字典:成功携领域值 `value`,失败携人读 `error`。\n * 软字典只允许出现在面向 LLM 的 tools 适配层(把 Result 投影为 ToolResult 文案/isError)。\n */\nexport type Result<T> = { ok: true; value: T } | { ok: false; error: string }\n\nexport interface DispatchOutcome {\n id: string\n status: TaskStatus\n output?: string\n}\n\nexport interface TaskBrief {\n id: string\n prompt: string\n status: TaskStatus\n}\n\nexport interface BackgroundOutput {\n status: TaskStatus\n output?: string\n}\n\n/** 编排工作流配置(M-B3 单源——consumed by orchestrator & setting)。 */\nexport interface WorkflowOptions {\n retry?: { enabled?: boolean; maxAttempts?: number }\n circuitBreaker?: { enabled?: boolean; failureThreshold?: number; timeoutMs?: number }\n}\n","/**\n * 委派深度护栏单源(RFC-057 M90-01 / §6 规则 5 / §10 C14)。\n *\n * `childDepth = (depth ?? 0) + 1`;`exceeded = childDepth > max`。\n * 三处调用点共用,消字节级重复:\n * - orchestrator `dispatchTask`(task_delegate sync/background)\n * - orchestrator `callAgent`(agent_call 轻量旁路)\n * - tools `fork_call`(字节继承旁路)\n *\n * 注意(§10 C14):本轴是「跨委派深度」(一个 agent 能向子 agent 委派多少层,默认 max=1),\n * 与 swarm `MAX_NESTING_DEPTH=5`(team 内部嵌套递归轴)是**同名不同概念**,不得并入。\n */\nexport interface DelegationDepthCheck {\n /** 子委派的深度(父 depth + 1),传给被委派会话。 */\n childDepth: number\n /** childDepth 是否越过 max(越过则应拒绝委派)。 */\n exceeded: boolean\n}\n\nexport function checkDelegationDepth(depth: number | undefined, max: number): DelegationDepthCheck {\n const childDepth = (depth ?? 0) + 1\n return { childDepth, exceeded: childDepth > max }\n}\n","import type { TodoItem } from './primitives'\nimport type { WriteTodos } from './callbacks'\n\n// orchestration-contracts/src/todo-store.ts — Session-level Todo store.\n// Extracted from orchestrator.ts (endgame architecture review O2).\nexport function createTodoStore(): WriteTodos {\n const storeBySession = new Map<string, TodoItem[]>()\n\n return async ({ action, todos, sessionId }) => {\n const sessionKey = sessionId?.trim() || '__default__'\n let store = storeBySession.get(sessionKey) ?? []\n\n if (action === 'set') {\n store = [...todos]\n } else {\n const map = new Map(store.map((t) => [t.id, t]))\n for (const todo of todos) {\n map.set(todo.id, todo)\n }\n store = [...map.values()]\n }\n\n storeBySession.set(sessionKey, store)\n return { ok: true, value: store }\n }\n}\n"],"mappings":"AAKA,MAAa,EAAc,CAAC,SAAU,WAAY,UAAW,WAAY,SAAS,CCclF,SAAgB,EAAqB,EAA2B,EAAmC,CACjG,IAAM,GAAc,GAAS,GAAK,EAClC,MAAO,CAAE,aAAY,SAAU,EAAa,EAAK,CChBnD,SAAgB,GAA8B,CAC5C,IAAM,EAAiB,IAAI,IAE3B,OAAO,MAAO,CAAE,SAAQ,QAAO,eAAgB,CAC7C,IAAM,EAAa,GAAW,MAAM,EAAI,cACpC,EAAQ,EAAe,IAAI,EAAW,EAAI,EAAE,CAEhD,GAAI,IAAW,MACb,EAAQ,CAAC,GAAG,EAAM,KACb,CACL,IAAM,EAAM,IAAI,IAAI,EAAM,IAAK,GAAM,CAAC,EAAE,GAAI,EAAE,CAAC,CAAC,CAChD,IAAK,IAAM,KAAQ,EACjB,EAAI,IAAI,EAAK,GAAI,EAAK,CAExB,EAAQ,CAAC,GAAG,EAAI,QAAQ,CAAC,CAI3B,OADA,EAAe,IAAI,EAAY,EAAM,CAC9B,CAAE,GAAI,GAAM,MAAO,EAAO"}
package/package.json ADDED
@@ -0,0 +1,31 @@
1
+ {
2
+ "name": "@x-otto/orchestration-contracts",
3
+ "version": "0.0.1-alpha.0",
4
+ "files": [
5
+ "dist"
6
+ ],
7
+ "type": "module",
8
+ "main": "./dist/index.js",
9
+ "types": "./dist/index.d.ts",
10
+ "exports": {
11
+ ".": {
12
+ "types": "./dist/index.d.ts",
13
+ "import": "./dist/index.js"
14
+ }
15
+ },
16
+ "publishConfig": {
17
+ "access": "public",
18
+ "registry": "https://registry.npmjs.org",
19
+ "tag": "alpha"
20
+ },
21
+ "dependencies": {
22
+ "@x-otto/interchange": "0.1.0-alpha.1"
23
+ },
24
+ "private": false,
25
+ "scripts": {
26
+ "build": "tsdown",
27
+ "typecheck:project": "tsc -p tsconfig.json --noEmit",
28
+ "typecheck": "tsc --noEmit",
29
+ "clean": "rm -rf dist"
30
+ }
31
+ }