@mawaru/sdk 0.32.0 → 0.34.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.
@@ -1,6 +1,8 @@
1
1
  import { describe, expect, it } from "vitest"
2
+ import { MODEL_SERIES } from "../../agent-runner/_agents/models.js"
2
3
  import {
3
4
  AI_MODEL_GROUPS,
5
+ AI_MODEL_SERIES,
4
6
  AI_MODELS,
5
7
  agentOfModel,
6
8
  aiManifestSchema,
@@ -52,12 +54,12 @@ describe("aiManifestSchema", () => {
52
54
  outputs: { main: textOutput },
53
55
  })
54
56
  expect(manifest.name).toBeUndefined()
55
- expect(manifest.model).toBe("claude-opus-5")
57
+ expect(manifest.model).toBe("claude-opus")
56
58
  expect(manifest.skills).toEqual([])
57
59
  expect(manifest.env).toEqual([])
58
60
  })
59
61
 
60
- it("model は AI_MODELS の enum(バージョン固定。外の値は拒否)", () => {
62
+ it("model は AI_MODELS の enum(系列か固定 ID。外の値は拒否)", () => {
61
63
  for (const model of AI_MODELS) {
62
64
  expect(aiManifestSchema.parse({ ...valid, model }).model).toBe(model)
63
65
  }
@@ -80,19 +82,36 @@ describe("aiManifestSchema", () => {
80
82
  expect(
81
83
  aiManifestSchema.parse({ ...valid, model: "gpt-6-astra" }).model,
82
84
  ).toBe("gpt-6-astra")
83
- for (const model of AI_MODEL_GROUPS.claude.models) {
85
+ const { claude, codex } = AI_MODEL_GROUPS
86
+ for (const model of [...claude.series, ...claude.models]) {
84
87
  expect(agentOfModel(model)).toBe("claude")
85
88
  }
86
- for (const model of AI_MODEL_GROUPS.codex.models) {
89
+ for (const model of [...codex.series, ...codex.models]) {
87
90
  expect(agentOfModel(model)).toBe("codex")
88
91
  }
89
- // 各グループの既定はそのグループの選択肢に含まれる
90
- expect(AI_MODEL_GROUPS.claude.models).toContain(
91
- AI_MODEL_GROUPS.claude.default,
92
- )
93
- expect(AI_MODEL_GROUPS.codex.models).toContain(
94
- AI_MODEL_GROUPS.codex.default,
92
+ // 各グループの既定はそのグループの系列(最新追従)
93
+ expect(claude.series).toContain(claude.default)
94
+ expect(codex.series).toContain(codex.default)
95
+ })
96
+
97
+ it("系列(最新追従)を選べる。既定は claude-opus", () => {
98
+ for (const model of ["claude-opus", "gpt-sol"]) {
99
+ expect(aiManifestSchema.parse({ ...valid, model }).model).toBe(model)
100
+ }
101
+ expect(AI_MODEL_GROUPS.claude.default).toBe("claude-opus")
102
+ })
103
+
104
+ it("系列の一覧は runner の対応表と一致し、読み替え先は同じグループの固定 ID", () => {
105
+ // runner は npm 公開パッケージで sdk に依存できず、系列名は二重管理になる。
106
+ // どちらかに足し忘れたらここで落ちる
107
+ expect(Object.keys(MODEL_SERIES).sort()).toEqual(
108
+ [...AI_MODEL_SERIES].sort(),
95
109
  )
110
+ for (const group of Object.values(AI_MODEL_GROUPS)) {
111
+ for (const series of group.series) {
112
+ expect(group.models).toContain(MODEL_SERIES[series])
113
+ }
114
+ }
96
115
  })
97
116
 
98
117
  it("inputs は key 自由・1件以上(in / instruction の固定構成は廃止)", () => {
@@ -6,12 +6,19 @@ import { jsonSchemaSchema, PORT_KEY_PATTERN } from "./node.js"
6
6
  // config.json に agent のようなフィールドは持たず、model の接頭辞(claude-* / gpt-*)で決まる
7
7
  // (runner の _agents/index.ts と同じ規則。AI実行エージェントの抽象化(Claude CodeとCodex).md)。
8
8
  //
9
- // モデルはエイリアス("opus" 等)を採らずバージョンを固定する:実行のたびに黙って別モデルへ
10
- // 乗り換わると品質も費用も再現しないため。新モデルが出たらこの配列を足して SDK を publish する。
11
- // 既定は Opus:下書き品質が価値の中心。費用はユーザー持ち
9
+ // model に書けるのは「系列」か「固定 ID」のどちらか
10
+ // (docs/tasks: AIノードのモデルを常に最新にする(系列指定).md)。
11
+ // - series=系列(claude-opus 等)。その系列の最新モデルで走る。どの実 ID に当たるかは
12
+ // runner の対応表(agent-runner の _agents/models.ts)が実行時に決めるので、新モデルが
13
+ // 出たら対応表を直すだけで全ノードが追従する(各 repo の config.json は触らない)。
14
+ // 系列名の一覧はここと runner の二重管理(ai-manifest.test.ts が一致を検証する)
15
+ // - models=固定 ID。そのバージョンで走り続ける(新モデルで崩れたノードを戻す手段)
16
+ // 系列をまたいでは上がらない(費用はユーザー持ち。Opus 指定が Fable になることは無い)。
17
+ // 既定は Opus の系列:下書き品質が価値の中心
12
18
  export const AI_MODEL_GROUPS = {
13
19
  claude: {
14
20
  name: "Claude Code",
21
+ series: ["claude-fable", "claude-opus", "claude-sonnet", "claude-haiku"],
15
22
  models: [
16
23
  "claude-fable-5-1",
17
24
  "claude-fable-5",
@@ -20,25 +27,34 @@ export const AI_MODEL_GROUPS = {
20
27
  "claude-sonnet-5",
21
28
  "claude-haiku-4-5",
22
29
  ],
23
- default: "claude-opus-5",
30
+ default: "claude-opus",
24
31
  },
32
+ // astra=最上位 / sol=主力 / luna=軽量。terra は GPT-5.6 世代にしか無いので系列にしない
25
33
  codex: {
26
34
  name: "Codex",
35
+ series: ["gpt-astra", "gpt-sol", "gpt-luna"],
27
36
  models: [
37
+ "gpt-6.1-sol",
28
38
  "gpt-6-astra",
39
+ "gpt-6-sol",
40
+ "gpt-6-luna",
29
41
  "gpt-5.6-sol",
30
42
  "gpt-5.6-terra",
31
43
  "gpt-5.6-luna",
32
- "gpt-5.5",
33
44
  ],
34
- default: "gpt-6-astra",
45
+ default: "gpt-astra",
35
46
  },
36
47
  } as const
37
48
  export const AI_AGENT_IDS = ["claude", "codex"] as const
38
49
  export const aiAgentIdSchema = z.enum(AI_AGENT_IDS)
39
50
  export type AiAgentId = z.infer<typeof aiAgentIdSchema>
40
51
 
52
+ export const AI_MODEL_SERIES = [
53
+ ...AI_MODEL_GROUPS.claude.series,
54
+ ...AI_MODEL_GROUPS.codex.series,
55
+ ] as const
41
56
  export const AI_MODELS = [
57
+ ...AI_MODEL_SERIES,
42
58
  ...AI_MODEL_GROUPS.claude.models,
43
59
  ...AI_MODEL_GROUPS.codex.models,
44
60
  ] as const
@@ -908,6 +908,16 @@ describe("saveGraphBodySchema(refs:ループ変数の定義スキーマ)",
908
908
  ).toThrow(/required/)
909
909
  })
910
910
 
911
+ it("properties に予約キー input(run の起動入力)は置けない", () => {
912
+ expect(() =>
913
+ saveGraphBodySchema.parse({
914
+ nodes: [makeNode()],
915
+ connections: [],
916
+ refs: { type: "object", properties: { input: { type: "string" } } },
917
+ }),
918
+ ).toThrow(/input/)
919
+ })
920
+
911
921
  it("object 以外の type・旧「値の袋」形は拒否する", () => {
912
922
  for (const refs of [
913
923
  { type: "string" },
package/_schemas/graph.ts CHANGED
@@ -20,6 +20,12 @@ import {
20
20
  export const refsBagSchema = z.record(portKeySchema, z.unknown())
21
21
  export type RefsBag = z.infer<typeof refsBagSchema>
22
22
 
23
+ // 予約キー:run の起動入力(runs.start_payload)。Run.start が袋に写し、全 step
24
+ // (Program の refs.json・AI のプロンプト・承認ビューの ctx)から読める。
25
+ // ループ定義には置けず、起動指定・end のパッチでも書けない
26
+ // (起動入力をrefsに入れて全ノードから参照できるようにする.md)
27
+ export const REFS_INPUT_KEY = "input"
28
+
23
29
  // ループ変数の定義=袋全体を表す 1 つの object JSON Schema
24
30
  // (ループ変数(refs)のJSON Schema化.md)。properties のキーが変数名、
25
31
  // default が静的なデフォルト値、required は「run 起動時に値が確定して
@@ -31,6 +37,13 @@ export const loopRefsSchema = z
31
37
  required: z.array(portKeySchema).optional(),
32
38
  })
33
39
  .superRefine((refs, ctx) => {
40
+ if (REFS_INPUT_KEY in refs.properties) {
41
+ ctx.addIssue({
42
+ code: "custom",
43
+ path: ["properties", REFS_INPUT_KEY],
44
+ message: `properties のキー ${REFS_INPUT_KEY} は予約キー(run の起動入力)です`,
45
+ })
46
+ }
34
47
  for (const key of refs.required ?? []) {
35
48
  if (!(key in refs.properties)) {
36
49
  ctx.addIssue({
@@ -2,13 +2,15 @@ import { z } from "zod";
2
2
  export declare const AI_MODEL_GROUPS: {
3
3
  readonly claude: {
4
4
  readonly name: "Claude Code";
5
+ readonly series: readonly ["claude-fable", "claude-opus", "claude-sonnet", "claude-haiku"];
5
6
  readonly models: readonly ["claude-fable-5-1", "claude-fable-5", "claude-opus-5", "claude-opus-4-8", "claude-sonnet-5", "claude-haiku-4-5"];
6
- readonly default: "claude-opus-5";
7
+ readonly default: "claude-opus";
7
8
  };
8
9
  readonly codex: {
9
10
  readonly name: "Codex";
10
- readonly models: readonly ["gpt-6-astra", "gpt-5.6-sol", "gpt-5.6-terra", "gpt-5.6-luna", "gpt-5.5"];
11
- readonly default: "gpt-6-astra";
11
+ readonly series: readonly ["gpt-astra", "gpt-sol", "gpt-luna"];
12
+ readonly models: readonly ["gpt-6.1-sol", "gpt-6-astra", "gpt-6-sol", "gpt-6-luna", "gpt-5.6-sol", "gpt-5.6-terra", "gpt-5.6-luna"];
13
+ readonly default: "gpt-astra";
12
14
  };
13
15
  };
14
16
  export declare const AI_AGENT_IDS: readonly ["claude", "codex"];
@@ -17,22 +19,32 @@ export declare const aiAgentIdSchema: z.ZodEnum<{
17
19
  codex: "codex";
18
20
  }>;
19
21
  export type AiAgentId = z.infer<typeof aiAgentIdSchema>;
20
- export declare const AI_MODELS: readonly ["claude-fable-5-1", "claude-fable-5", "claude-opus-5", "claude-opus-4-8", "claude-sonnet-5", "claude-haiku-4-5", "gpt-6-astra", "gpt-5.6-sol", "gpt-5.6-terra", "gpt-5.6-luna", "gpt-5.5"];
22
+ export declare const AI_MODEL_SERIES: readonly ["claude-fable", "claude-opus", "claude-sonnet", "claude-haiku", "gpt-astra", "gpt-sol", "gpt-luna"];
23
+ export declare const AI_MODELS: readonly ["claude-fable", "claude-opus", "claude-sonnet", "claude-haiku", "gpt-astra", "gpt-sol", "gpt-luna", "claude-fable-5-1", "claude-fable-5", "claude-opus-5", "claude-opus-4-8", "claude-sonnet-5", "claude-haiku-4-5", "gpt-6.1-sol", "gpt-6-astra", "gpt-6-sol", "gpt-6-luna", "gpt-5.6-sol", "gpt-5.6-terra", "gpt-5.6-luna"];
21
24
  export declare const aiModelSchema: z.ZodEnum<{
25
+ "claude-fable": "claude-fable";
26
+ "claude-opus": "claude-opus";
27
+ "claude-sonnet": "claude-sonnet";
28
+ "claude-haiku": "claude-haiku";
22
29
  "claude-fable-5-1": "claude-fable-5-1";
23
30
  "claude-fable-5": "claude-fable-5";
24
31
  "claude-opus-5": "claude-opus-5";
25
32
  "claude-opus-4-8": "claude-opus-4-8";
26
33
  "claude-sonnet-5": "claude-sonnet-5";
27
34
  "claude-haiku-4-5": "claude-haiku-4-5";
35
+ "gpt-astra": "gpt-astra";
36
+ "gpt-sol": "gpt-sol";
37
+ "gpt-luna": "gpt-luna";
38
+ "gpt-6.1-sol": "gpt-6.1-sol";
28
39
  "gpt-6-astra": "gpt-6-astra";
40
+ "gpt-6-sol": "gpt-6-sol";
41
+ "gpt-6-luna": "gpt-6-luna";
29
42
  "gpt-5.6-sol": "gpt-5.6-sol";
30
43
  "gpt-5.6-terra": "gpt-5.6-terra";
31
44
  "gpt-5.6-luna": "gpt-5.6-luna";
32
- "gpt-5.5": "gpt-5.5";
33
45
  }>;
34
46
  export type AiModel = z.infer<typeof aiModelSchema>;
35
- export declare const DEFAULT_AI_MODEL: "claude-opus-5";
47
+ export declare const DEFAULT_AI_MODEL: "claude-opus";
36
48
  export declare const agentOfModel: (model: AiModel) => AiAgentId;
37
49
  export declare const aiInputDeclSchema: z.ZodObject<{
38
50
  schema: z.ZodRecord<z.ZodString, z.ZodUnknown>;
@@ -44,17 +56,26 @@ export declare const aiManifestSchema: z.ZodObject<{
44
56
  description: z.ZodOptional<z.ZodString>;
45
57
  prompt: z.ZodString;
46
58
  model: z.ZodDefault<z.ZodEnum<{
59
+ "claude-fable": "claude-fable";
60
+ "claude-opus": "claude-opus";
61
+ "claude-sonnet": "claude-sonnet";
62
+ "claude-haiku": "claude-haiku";
47
63
  "claude-fable-5-1": "claude-fable-5-1";
48
64
  "claude-fable-5": "claude-fable-5";
49
65
  "claude-opus-5": "claude-opus-5";
50
66
  "claude-opus-4-8": "claude-opus-4-8";
51
67
  "claude-sonnet-5": "claude-sonnet-5";
52
68
  "claude-haiku-4-5": "claude-haiku-4-5";
69
+ "gpt-astra": "gpt-astra";
70
+ "gpt-sol": "gpt-sol";
71
+ "gpt-luna": "gpt-luna";
72
+ "gpt-6.1-sol": "gpt-6.1-sol";
53
73
  "gpt-6-astra": "gpt-6-astra";
74
+ "gpt-6-sol": "gpt-6-sol";
75
+ "gpt-6-luna": "gpt-6-luna";
54
76
  "gpt-5.6-sol": "gpt-5.6-sol";
55
77
  "gpt-5.6-terra": "gpt-5.6-terra";
56
78
  "gpt-5.6-luna": "gpt-5.6-luna";
57
- "gpt-5.5": "gpt-5.5";
58
79
  }>>;
59
80
  auth_mode: z.ZodOptional<z.ZodEnum<{
60
81
  subscription: "subscription";
@@ -5,12 +5,19 @@ import { jsonSchemaSchema, PORT_KEY_PATTERN } from "./node.js";
5
5
  // config.json に agent のようなフィールドは持たず、model の接頭辞(claude-* / gpt-*)で決まる
6
6
  // (runner の _agents/index.ts と同じ規則。AI実行エージェントの抽象化(Claude CodeとCodex).md)。
7
7
  //
8
- // モデルはエイリアス("opus" 等)を採らずバージョンを固定する:実行のたびに黙って別モデルへ
9
- // 乗り換わると品質も費用も再現しないため。新モデルが出たらこの配列を足して SDK を publish する。
10
- // 既定は Opus:下書き品質が価値の中心。費用はユーザー持ち
8
+ // model に書けるのは「系列」か「固定 ID」のどちらか
9
+ // (docs/tasks: AIノードのモデルを常に最新にする(系列指定).md)。
10
+ // - series=系列(claude-opus 等)。その系列の最新モデルで走る。どの実 ID に当たるかは
11
+ // runner の対応表(agent-runner の _agents/models.ts)が実行時に決めるので、新モデルが
12
+ // 出たら対応表を直すだけで全ノードが追従する(各 repo の config.json は触らない)。
13
+ // 系列名の一覧はここと runner の二重管理(ai-manifest.test.ts が一致を検証する)
14
+ // - models=固定 ID。そのバージョンで走り続ける(新モデルで崩れたノードを戻す手段)
15
+ // 系列をまたいでは上がらない(費用はユーザー持ち。Opus 指定が Fable になることは無い)。
16
+ // 既定は Opus の系列:下書き品質が価値の中心
11
17
  export const AI_MODEL_GROUPS = {
12
18
  claude: {
13
19
  name: "Claude Code",
20
+ series: ["claude-fable", "claude-opus", "claude-sonnet", "claude-haiku"],
14
21
  models: [
15
22
  "claude-fable-5-1",
16
23
  "claude-fable-5",
@@ -19,23 +26,32 @@ export const AI_MODEL_GROUPS = {
19
26
  "claude-sonnet-5",
20
27
  "claude-haiku-4-5",
21
28
  ],
22
- default: "claude-opus-5",
29
+ default: "claude-opus",
23
30
  },
31
+ // astra=最上位 / sol=主力 / luna=軽量。terra は GPT-5.6 世代にしか無いので系列にしない
24
32
  codex: {
25
33
  name: "Codex",
34
+ series: ["gpt-astra", "gpt-sol", "gpt-luna"],
26
35
  models: [
36
+ "gpt-6.1-sol",
27
37
  "gpt-6-astra",
38
+ "gpt-6-sol",
39
+ "gpt-6-luna",
28
40
  "gpt-5.6-sol",
29
41
  "gpt-5.6-terra",
30
42
  "gpt-5.6-luna",
31
- "gpt-5.5",
32
43
  ],
33
- default: "gpt-6-astra",
44
+ default: "gpt-astra",
34
45
  },
35
46
  };
36
47
  export const AI_AGENT_IDS = ["claude", "codex"];
37
48
  export const aiAgentIdSchema = z.enum(AI_AGENT_IDS);
49
+ export const AI_MODEL_SERIES = [
50
+ ...AI_MODEL_GROUPS.claude.series,
51
+ ...AI_MODEL_GROUPS.codex.series,
52
+ ];
38
53
  export const AI_MODELS = [
54
+ ...AI_MODEL_SERIES,
39
55
  ...AI_MODEL_GROUPS.claude.models,
40
56
  ...AI_MODEL_GROUPS.codex.models,
41
57
  ];
@@ -1,6 +1,7 @@
1
1
  import { z } from "zod";
2
2
  export declare const refsBagSchema: z.ZodRecord<z.ZodString, z.ZodUnknown>;
3
3
  export type RefsBag = z.infer<typeof refsBagSchema>;
4
+ export declare const REFS_INPUT_KEY = "input";
4
5
  export declare const loopRefsSchema: z.ZodObject<{
5
6
  type: z.ZodLiteral<"object">;
6
7
  properties: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
@@ -6,6 +6,11 @@ import { hasInboundConflict, isSchemaSubset, kindPortsViolation, resolvePortSche
6
6
  // key はポート key と同じ規則(^[a-z][a-z0-9_]*$)。実行系ボディ
7
7
  // (run 起動の上書き・step end のパッチ)が使う契約
8
8
  export const refsBagSchema = z.record(portKeySchema, z.unknown());
9
+ // 予約キー:run の起動入力(runs.start_payload)。Run.start が袋に写し、全 step
10
+ // (Program の refs.json・AI のプロンプト・承認ビューの ctx)から読める。
11
+ // ループ定義には置けず、起動指定・end のパッチでも書けない
12
+ // (起動入力をrefsに入れて全ノードから参照できるようにする.md)
13
+ export const REFS_INPUT_KEY = "input";
9
14
  // ループ変数の定義=袋全体を表す 1 つの object JSON Schema
10
15
  // (ループ変数(refs)のJSON Schema化.md)。properties のキーが変数名、
11
16
  // default が静的なデフォルト値、required は「run 起動時に値が確定して
@@ -17,6 +22,13 @@ export const loopRefsSchema = z
17
22
  required: z.array(portKeySchema).optional(),
18
23
  })
19
24
  .superRefine((refs, ctx) => {
25
+ if (REFS_INPUT_KEY in refs.properties) {
26
+ ctx.addIssue({
27
+ code: "custom",
28
+ path: ["properties", REFS_INPUT_KEY],
29
+ message: `properties のキー ${REFS_INPUT_KEY} は予約キー(run の起動入力)です`,
30
+ });
31
+ }
20
32
  for (const key of refs.required ?? []) {
21
33
  if (!(key in refs.properties)) {
22
34
  ctx.addIssue({
package/dist/typegen.js CHANGED
@@ -1,6 +1,7 @@
1
1
  import { createHash } from "node:crypto";
2
2
  import { existsSync, readdirSync, readFileSync, writeFileSync } from "node:fs";
3
3
  import { join } from "node:path";
4
+ import { REFS_INPUT_KEY } from "./_schemas/graph.js";
4
5
  import { programManifestSchema, } from "./_schemas/program-manifest.js";
5
6
  // 生成ファイルに刻む config.json 内容のハッシュ。validate が drift(config を変えて
6
7
  // typegen し忘れ)の検出に使う
@@ -139,8 +140,12 @@ export const renderTypesFile = (manifest, rawConfig) => {
139
140
  const inputSchema = manifest.inputs.in ?? {};
140
141
  const outputEntries = Object.entries(manifest.outputs).map(([key, schema]) => ` ${propertyKey(key)}: ${tsTypeFromJsonSchema(schema, 1)}`);
141
142
  // refs=ループ変数の袋(実行時に refs.json で渡される)。config の refs はループ定義
142
- // からの転写(キー→推定型)なので、宣言が無ければ型も出さない
143
- const refEntries = Object.entries(manifest.refs).map(([key, schema]) => ` ${propertyKey(key)}: ${tsTypeFromJsonSchema(schema, 1)}`);
143
+ // からの転写(キー→推定型)。予約キー input(run の起動入力)は定義に現れないが
144
+ // 必ず袋に載るので、宣言が無くても Refs / Ctx を出す
145
+ const refEntries = [
146
+ ` ${propertyKey(REFS_INPUT_KEY)}: unknown`,
147
+ ...Object.entries(manifest.refs).map(([key, schema]) => ` ${propertyKey(key)}: ${tsTypeFromJsonSchema(schema, 1)}`),
148
+ ];
144
149
  return [
145
150
  "// このファイルは mawaru typegen が config.json から自動生成した(手で編集しない)",
146
151
  `${CONFIG_HASH_PREFIX}${configHash(rawConfig)}`,
@@ -152,16 +157,13 @@ export const renderTypesFile = (manifest, rawConfig) => {
152
157
  "// run の戻り値:ちょうど1つの出口ポートのキーで返す { <出口キー>: 値 }",
153
158
  outputUnionType(Object.keys(manifest.outputs)),
154
159
  "",
155
- ...(refEntries.length > 0
156
- ? [
157
- `export type Refs = {\n${refEntries.join("\n")}\n}`,
158
- "",
159
- "// run の第2引数:refs=届いた袋の読み、setRefs=袋へのパッチの宣言",
160
- "// (書いたキーだけが完了時に袋へマージされ、下流のノードから読める)",
161
- "export type Ctx = { refs: Refs; setRefs: (patch: Partial<Refs>) => void }",
162
- "",
163
- ]
164
- : []),
160
+ `export type Refs = {\n${refEntries.join("\n")}\n}`,
161
+ "",
162
+ "// run の第2引数:refs=届いた袋の読み、setRefs=袋へのパッチの宣言",
163
+ "// (書いたキーだけが完了時に袋へマージされ、下流のノードから読める。",
164
+ "// input は run の起動入力=読み専用)",
165
+ "export type Ctx = { refs: Refs; setRefs: (patch: Partial<Refs>) => void }",
166
+ "",
165
167
  ].join("\n");
166
168
  };
167
169
  // nodes/program/ 直下の各 dir の config.json から types.d.ts を生成する
@@ -30,7 +30,9 @@ skills/<dir>/ # AI ノードが参照する skill(SKILL.md)
30
30
  - `{ <出口ポートのkey>: <データ> }` の**単一キーのオブジェクト**(どの出口から出るかを戻り値自身が運ぶ)
31
31
  - `"pending"` — 完了保留(外部イベントで後から end が届く)
32
32
  - `ctx` — ループ変数の袋の読み書き:
33
- - `ctx.refs` — 届いた袋(loop に定義された変数の、この step 開始時点の値)
33
+ - `ctx.refs` — 届いた袋(loop に定義された変数の、この step 開始時点の値)。
34
+ 予約キー `ctx.refs.input` は **run の起動入力**(開始ノードに渡された値。コンポーネントの
35
+ 中ならコンポーネントの入力)。読み専用で、loop の定義には置けず `setRefs` でも書けない
34
36
  - `ctx.setRefs({ key: value })` — 袋へのパッチの宣言。**完了時にだけ**反映され、以降の
35
37
  ノードが `ctx.refs` で読める(動的な値を下流へ渡す唯一の経路)。何度呼んでもトップレベル
36
38
  キー後勝ちで畳まれる。`"pending"` を返す実行では反映されない。loop に定義の無いキーを
@@ -47,7 +49,9 @@ skills/<dir>/ # AI ノードが参照する skill(SKILL.md)
47
49
  - `config.json` — 正は `_schemas/ai-manifest.ts`。`prompt`(必須)・`model`・
48
50
  `skills`(トップレベル `skills/` 配下のディレクトリ名)・`env`・`inputs` / `outputs`
49
51
  - `model` が実行主体を決める:`claude-*` は Claude Code、`gpt-*` は Codex で走る
50
- (選択肢は `AI_MODEL_GROUPS`)。認証は repo の Actions secrets に置く:Claude Code は
52
+ (選択肢は `AI_MODEL_GROUPS`)。値は系列(`claude-opus`・`gpt-sol` 等。その系列の最新モデルで
53
+ 走り、新モデルが出れば自動で切り替わる)か、固定 ID(`claude-opus-5` 等。そのバージョンで
54
+ 走り続ける)。省略時は `claude-opus`。認証は repo の Actions secrets に置く:Claude Code は
51
55
  `ANTHROPIC_API_KEY`(または `CLAUDE_CODE_OAUTH_TOKEN`)、Codex は明示的な `auth_mode` と対応する認証情報(下記「Codex の認証方式」参照)
52
56
  (`env` に宣言しなくても渡される)
53
57
  - `inputs` は1件以上・key 自由。値は `{ "schema": <JSON Schema>, "resume": true }` の形
@@ -89,7 +93,7 @@ Codex の AI 定義は `auth_mode` を必ず指定する。エディタの「認
89
93
  ```json
90
94
  {
91
95
  "prompt": "入力に返信してください",
92
- "model": "gpt-5.6-luna",
96
+ "model": "gpt-luna",
93
97
  "auth_mode": "subscription",
94
98
  "inputs": { "in": { "schema": {} } },
95
99
  "outputs": { "main": { "type": "string" } }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mawaru/sdk",
3
- "version": "0.32.0",
3
+ "version": "0.34.0",
4
4
  "description": "mawaru 実行 repo の開発 SDK。契約スキーマ(config.json 規約・ループ graph API)の正 + typegen / validate CLI",
5
5
  "type": "module",
6
6
  "bin": {
@@ -87,7 +87,8 @@ repo との矛盾・使用中ノードの削除は 409。**graph PUT は冪等
87
87
  - kind 別の固定ポート構成(human / wait / ai)は `port-spec.ts` の `kindPortsViolation` に従う
88
88
  - ループ変数(refs=run 全体で読める key→値 の袋)が要るならトップレベルの `refs` に入れる。
89
89
  ノード単位の宣言やバインドは無い。handler は実行時に `refs.json` で全量を受け取り、
90
- `end` の `refs` パッチで値を更新できる(config.json の `refs` はループ定義からの転写=生成物)
90
+ `end` の `refs` パッチで値を更新できる(config.json の `refs` はループ定義からの転写=生成物)。
91
+ キー `input` は予約(run の起動入力が自動で入る。定義に置くと 422)
91
92
  - `position_x` / `position_y` は左→右に流れる単純配置(例: x を 320 刻み、y は 240)
92
93
  5. **保存**:`PUT loops/{loopId}/graph`。400 / 422 / 409 ならメッセージを読んで直して再送。
93
94
  6. **報告**:エディタ URL `{MAWARU_APP_URL}/loops/{loopId}/edit` をユーザーに渡し、