create-windy 0.4.1 → 0.5.1

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 (174) hide show
  1. package/dist/cli.js +292 -125
  2. package/package.json +1 -1
  3. package/template/.windy-template.json +2 -2
  4. package/template/apps/agent-server/adk_web_agents/canonical_debug/agent.py +29 -9
  5. package/template/apps/agent-server/adk_web_agents/services.py +25 -0
  6. package/template/apps/agent-server/src/southwind_agent_server/adk_adapter.py +40 -11
  7. package/template/apps/agent-server/src/southwind_agent_server/adk_debug_sessions.py +325 -0
  8. package/template/apps/agent-server/src/southwind_agent_server/adk_model.py +70 -6
  9. package/template/apps/agent-server/src/southwind_agent_server/adk_tools.py +1 -1
  10. package/template/apps/agent-server/src/southwind_agent_server/app.py +16 -4
  11. package/template/apps/agent-server/src/southwind_agent_server/approval_resolution.py +30 -0
  12. package/template/apps/agent-server/src/southwind_agent_server/contracts.py +9 -0
  13. package/template/apps/agent-server/src/southwind_agent_server/deterministic.py +2 -1
  14. package/template/apps/agent-server/src/southwind_agent_server/engine.py +3 -1
  15. package/template/apps/agent-server/src/southwind_agent_server/openai_engine.py +95 -130
  16. package/template/apps/agent-server/src/southwind_agent_server/openai_engine_validation.py +133 -0
  17. package/template/apps/agent-server/src/southwind_agent_server/openai_provider.py +89 -20
  18. package/template/apps/agent-server/src/southwind_agent_server/postgres_report_insert.py +34 -0
  19. package/template/apps/agent-server/src/southwind_agent_server/postgres_report_queries.py +234 -0
  20. package/template/apps/agent-server/src/southwind_agent_server/postgres_report_replay.py +44 -0
  21. package/template/apps/agent-server/src/southwind_agent_server/postgres_report_status.py +83 -0
  22. package/template/apps/agent-server/src/southwind_agent_server/postgres_report_store.py +331 -0
  23. package/template/apps/agent-server/src/southwind_agent_server/postgres_report_summary.py +304 -0
  24. package/template/apps/agent-server/src/southwind_agent_server/report_lifecycle.py +217 -0
  25. package/template/apps/agent-server/src/southwind_agent_server/report_metrics.py +149 -0
  26. package/template/apps/agent-server/src/southwind_agent_server/report_presenter.py +280 -0
  27. package/template/apps/agent-server/src/southwind_agent_server/report_routes.py +126 -0
  28. package/template/apps/agent-server/src/southwind_agent_server/report_store.py +344 -0
  29. package/template/apps/agent-server/src/southwind_agent_server/report_types.py +111 -0
  30. package/template/apps/agent-server/src/southwind_agent_server/runtime_factory.py +31 -2
  31. package/template/apps/agent-server/src/southwind_agent_server/service.py +56 -51
  32. package/template/apps/agent-server/src/southwind_agent_server/signal_events.py +18 -1
  33. package/template/apps/agent-server/tests/test_adk_adapter.py +7 -9
  34. package/template/apps/agent-server/tests/test_adk_debug_sessions.py +215 -0
  35. package/template/apps/agent-server/tests/test_adk_web_canonical_debug.py +48 -1
  36. package/template/apps/agent-server/tests/test_openai_provider.py +58 -6
  37. package/template/apps/agent-server/tests/test_postgres_report_status.py +59 -0
  38. package/template/apps/agent-server/tests/test_postgres_report_summary.py +298 -0
  39. package/template/apps/agent-server/tests/test_provider_attempt_reporting.py +152 -0
  40. package/template/apps/agent-server/tests/test_report_attempt_lifecycle.py +126 -0
  41. package/template/apps/agent-server/tests/test_report_resilience.py +181 -0
  42. package/template/apps/agent-server/tests/test_report_store.py +286 -0
  43. package/template/apps/agent-server/tests/test_report_summary_parity.py +115 -0
  44. package/template/apps/agent-server/tests/test_report_terminal_sync.py +177 -0
  45. package/template/apps/server/src/agent/debug-session-facade-provider-failure.test.ts +269 -0
  46. package/template/apps/server/src/agent/debug-session-facade.test.ts +335 -0
  47. package/template/apps/server/src/agent/debug-session-facade.ts +302 -0
  48. package/template/apps/server/src/agent/debug-session-id.test.ts +37 -0
  49. package/template/apps/server/src/agent/debug-session-id.ts +37 -0
  50. package/template/apps/server/src/agent/debug-session-provider-reader.ts +54 -0
  51. package/template/apps/server/src/agent/debug-session-routes.test.ts +64 -0
  52. package/template/apps/server/src/agent/debug-session-routes.ts +73 -0
  53. package/template/apps/server/src/agent/debug-session-validation.ts +106 -0
  54. package/template/apps/server/src/agent/drizzle-run-binding-repository.ts +2 -0
  55. package/template/apps/server/src/agent/provider-input-governance.test.ts +18 -0
  56. package/template/apps/server/src/agent/provider-input-governance.ts +37 -1
  57. package/template/apps/server/src/agent/remote-runtime.test.ts +7 -0
  58. package/template/apps/server/src/agent/remote-runtime.ts +1 -0
  59. package/template/apps/server/src/agent/run-authorization.test.ts +98 -0
  60. package/template/apps/server/src/agent/run-authorization.ts +32 -1
  61. package/template/apps/server/src/agent/run-binding-repository.ts +1 -0
  62. package/template/apps/server/src/agent/run-contracts.ts +5 -0
  63. package/template/apps/server/src/agent/run-facade-adk-debug.test.ts +39 -0
  64. package/template/apps/server/src/agent/run-facade.test.ts +78 -0
  65. package/template/apps/server/src/agent/run-facade.ts +33 -3
  66. package/template/apps/server/src/agent/run-input-commitment.ts +50 -0
  67. package/template/apps/server/src/agent/run-input-verification.ts +41 -0
  68. package/template/apps/server/src/agent/runtime-bootstrap-report.test.ts +136 -0
  69. package/template/apps/server/src/agent/runtime-bootstrap.ts +66 -1
  70. package/template/apps/server/src/agent/tool-host.test.ts +1 -0
  71. package/template/apps/server/src/agent/unavailable-routes.ts +4 -0
  72. package/template/apps/server/src/ai-runtime-report/actor-directory.ts +94 -0
  73. package/template/apps/server/src/ai-runtime-report/actor-handle.test.ts +27 -0
  74. package/template/apps/server/src/ai-runtime-report/actor-handle.ts +81 -0
  75. package/template/apps/server/src/ai-runtime-report/contracts.ts +91 -0
  76. package/template/apps/server/src/ai-runtime-report/remote-parser.ts +212 -0
  77. package/template/apps/server/src/ai-runtime-report/remote-port.ts +138 -0
  78. package/template/apps/server/src/ai-runtime-report/routes.ts +172 -0
  79. package/template/apps/server/src/ai-runtime-report/scope.ts +63 -0
  80. package/template/apps/server/src/ai-runtime-report/service.test.ts +271 -0
  81. package/template/apps/server/src/ai-runtime-report/service.ts +206 -0
  82. package/template/apps/server/src/license/runtime-audit-reliability.test.ts +2 -0
  83. package/template/apps/server/src/license/runtime-service.test.ts +6 -0
  84. package/template/apps/server/src/module-host/ai-operation-port.test.ts +63 -0
  85. package/template/apps/server/src/module-host/ai-operation-port.ts +30 -5
  86. package/template/apps/server/src/module-host/debug-session-provider-registration.test.ts +162 -0
  87. package/template/apps/server/src/module-host/debug-session-provider-registration.ts +84 -0
  88. package/template/apps/server/src/module-host/initialize-contracts.ts +7 -0
  89. package/template/apps/server/src/module-host/initialize.ts +6 -197
  90. package/template/apps/server/src/module-host/request-context.ts +1 -0
  91. package/template/apps/server/src/module-host/scoped-host.ts +214 -0
  92. package/template/apps/server/src/module-host.ts +1 -0
  93. package/template/apps/server/src/runtime-adk-debug.test.ts +25 -1
  94. package/template/apps/server/src/runtime-adk-debug.ts +8 -2
  95. package/template/apps/server/src/system/operations.test.ts +54 -0
  96. package/template/apps/server/src/system/operations.ts +23 -1
  97. package/template/apps/server/src/system/seed.test.ts +4 -0
  98. package/template/apps/server/src/system/system-resource-monitoring.test.ts +82 -0
  99. package/template/apps/server/src/system/system-resource-monitoring.ts +300 -0
  100. package/template/apps/web/src/layout/AppSidebar.vue +6 -1
  101. package/template/apps/web/src/layout/AppSidebar.webtest.ts +2 -0
  102. package/template/apps/web/src/pages/auth/LoginPage.vue +6 -1
  103. package/template/apps/web/src/pages/settings/BrandingSettingsSection.vue +20 -3
  104. package/template/apps/web/src/pages/settings/BrandingSettingsSection.webtest.ts +80 -0
  105. package/template/apps/web/src/pages/system/AiRuntimePage.vue +129 -0
  106. package/template/apps/web/src/pages/system/SystemOperationsPage.vue +2 -1
  107. package/template/apps/web/src/pages/system/ai-runtime-presenter.ts +60 -0
  108. package/template/apps/web/src/pages/system/ai-runtime-presenter.webtest.ts +48 -0
  109. package/template/apps/web/src/pages/system/audit-time-range.ts +34 -2
  110. package/template/apps/web/src/pages/system/components/AuditLogFilters.vue +4 -3
  111. package/template/apps/web/src/pages/system/components/AuditLogFilters.webtest.ts +26 -1
  112. package/template/apps/web/src/pages/system/components/OperationGpuMonitor.vue +98 -0
  113. package/template/apps/web/src/pages/system/components/OperationGpuMonitor.webtest.ts +61 -0
  114. package/template/apps/web/src/pages/system/components/OperationServiceMonitor.vue +53 -0
  115. package/template/apps/web/src/pages/system/components/OperationServiceMonitor.webtest.ts +20 -1
  116. package/template/apps/web/src/pages/system/components/SystemResourcePage.webtest.ts +14 -1
  117. package/template/apps/web/src/pages/system/components/ai-runtime/AiRuntimeActivityChart.vue +85 -0
  118. package/template/apps/web/src/pages/system/components/ai-runtime/AiRuntimeCharts.webtest.ts +82 -0
  119. package/template/apps/web/src/pages/system/components/ai-runtime/AiRuntimeFilters.vue +98 -0
  120. package/template/apps/web/src/pages/system/components/ai-runtime/AiRuntimeFilters.webtest.ts +27 -0
  121. package/template/apps/web/src/pages/system/components/ai-runtime/AiRuntimeRunDetailDialog.vue +168 -0
  122. package/template/apps/web/src/pages/system/components/ai-runtime/AiRuntimeRunTable.vue +130 -0
  123. package/template/apps/web/src/pages/system/components/ai-runtime/AiRuntimeSummaryCards.vue +82 -0
  124. package/template/apps/web/src/pages/system/components/ai-runtime/AiRuntimeSummaryCards.webtest.ts +102 -0
  125. package/template/apps/web/src/pages/system/components/ai-runtime/AiRuntimeTokenByModelChart.vue +101 -0
  126. package/template/apps/web/src/pages/system/composables/useAiRuntimeReport.ts +185 -0
  127. package/template/apps/web/src/pages/system/composables/useAiRuntimeReport.webtest.ts +158 -0
  128. package/template/apps/web/src/pages/system/composables/useSystemResource.ts +21 -7
  129. package/template/apps/web/src/router/error-navigation.ts +22 -0
  130. package/template/apps/web/src/router/index.ts +12 -23
  131. package/template/apps/web/src/router/platform-admin-route-bindings.ts +4 -0
  132. package/template/apps/web/src/services/ai-runtime-api.ts +164 -0
  133. package/template/apps/web/src/services/ai-runtime-api.webtest.ts +111 -0
  134. package/template/apps/web/src/services/operations-api.ts +28 -0
  135. package/template/docker-compose.agent-debug.yml +1 -1
  136. package/template/docs/architecture/ai-runtime.md +2 -1
  137. package/template/docs/architecture/module-host.md +3 -0
  138. package/template/docs/platform/agent-run-attestation.md +65 -0
  139. package/template/docs/platform/agent-runtime-observability.md +135 -0
  140. package/template/docs/platform/agent-runtime.md +47 -3
  141. package/template/docs/platform/operations-overview.md +13 -0
  142. package/template/docs/platform/platform-authentication.md +4 -3
  143. package/template/packages/config/package.json +1 -1
  144. package/template/packages/database/drizzle/0045_tiny_cassandra_nova.sql +65 -0
  145. package/template/packages/database/drizzle/0046_tranquil_living_mummy.sql +6 -0
  146. package/template/packages/database/drizzle/0047_oval_luke_cage.sql +18 -0
  147. package/template/packages/database/drizzle/meta/0045_snapshot.json +8814 -0
  148. package/template/packages/database/drizzle/meta/0046_snapshot.json +8820 -0
  149. package/template/packages/database/drizzle/meta/0047_snapshot.json +8835 -0
  150. package/template/packages/database/drizzle/meta/_journal.json +21 -0
  151. package/template/packages/database/package.json +1 -1
  152. package/template/packages/database/src/agent-runtime-schema.test.ts +54 -0
  153. package/template/packages/database/src/schema/agent-runtime.ts +114 -0
  154. package/template/packages/jobs/package.json +1 -1
  155. package/template/packages/modules/package.json +1 -1
  156. package/template/packages/modules/src/system-admin-routes.ts +10 -0
  157. package/template/packages/modules/src/system-admin-ui-catalog.ts +1 -1
  158. package/template/packages/modules/src/system-api-control-plane.ts +17 -1
  159. package/template/packages/modules/src/system-audit-actions.ts +10 -0
  160. package/template/packages/modules/src/system-features.ts +8 -0
  161. package/template/packages/modules/src/system-module-catalog.test.ts +35 -0
  162. package/template/packages/modules/src/system-module-catalog.ts +15 -4
  163. package/template/packages/modules/src/system-modules-access.test.ts +69 -0
  164. package/template/packages/modules/src/system-modules.ts +13 -0
  165. package/template/packages/modules/src/system-permissions.ts +2 -0
  166. package/template/packages/server-sdk/index.ts +11 -0
  167. package/template/packages/server-sdk/package.json +2 -1
  168. package/template/packages/server-sdk/src/ai-operation-port.ts +5 -0
  169. package/template/packages/server-sdk/src/debug-session-provider.ts +63 -0
  170. package/template/packages/server-sdk/src/module-host.ts +5 -0
  171. package/template/packages/shared/index.ts +3 -0
  172. package/template/packages/shared/package.json +1 -1
  173. package/template/packages/shared/src/ai-runtime-report.ts +134 -0
  174. package/template/scripts/lib/postgres-regression.ts +201 -0
@@ -316,6 +316,27 @@
316
316
  "when": 1785400645941,
317
317
  "tag": "0044_sweet_tarantula",
318
318
  "breakpoints": true
319
+ },
320
+ {
321
+ "idx": 45,
322
+ "version": "7",
323
+ "when": 1785432944198,
324
+ "tag": "0045_tiny_cassandra_nova",
325
+ "breakpoints": true
326
+ },
327
+ {
328
+ "idx": 46,
329
+ "version": "7",
330
+ "when": 1785437657721,
331
+ "tag": "0046_tranquil_living_mummy",
332
+ "breakpoints": true
333
+ },
334
+ {
335
+ "idx": 47,
336
+ "version": "7",
337
+ "when": 1785438653330,
338
+ "tag": "0047_oval_luke_cage",
339
+ "breakpoints": true
319
340
  }
320
341
  ]
321
342
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@southwind-ai/database",
3
- "version": "0.2.3",
3
+ "version": "0.3.0",
4
4
  "license": "UNLICENSED",
5
5
  "type": "module",
6
6
  "engines": {
@@ -4,6 +4,8 @@ import {
4
4
  agentEvaluationResults,
5
5
  agentOperationReleases,
6
6
  agentRunBindings,
7
+ agentRuntimeReportAttempts,
8
+ agentRuntimeReportRuns,
7
9
  agentRuntimeEvents,
8
10
  agentRuntimeRuns,
9
11
  } from "./schema/index.js";
@@ -30,8 +32,23 @@ test("Agent Run 固定不可变 Release 并持久化恢复租约", async () => {
30
32
  "agent_evaluation_results",
31
33
  );
32
34
  expect(getTableConfig(agentRunBindings).name).toBe("agent_run_bindings");
35
+ expect(agentRunBindings.inputDigestCommitment.notNull).toBe(true);
33
36
  expect(agentRunBindings.scopeSnapshot.notNull).toBe(true);
34
37
  expect(agentRunBindings.authorizationSnapshot.notNull).toBe(true);
38
+ expect(getTableConfig(agentRuntimeReportRuns).name).toBe(
39
+ "agent_runtime_report_runs",
40
+ );
41
+ expect(agentRuntimeReportRuns.actorId.notNull).toBe(false);
42
+ expect(getTableConfig(agentRuntimeReportAttempts).name).toBe(
43
+ "agent_runtime_report_attempts",
44
+ );
45
+ expect(agentRuntimeReportAttempts.cachedInputTokens.notNull).toBe(false);
46
+ expect(agentRuntimeReportAttempts.reasoningTokens.notNull).toBe(false);
47
+ expect(
48
+ getTableConfig(agentRuntimeReportAttempts).indexes.some(
49
+ (index) => index.config.name === "idx_agent_report_attempts_started",
50
+ ),
51
+ ).toBe(true);
35
52
 
36
53
  const migration = await Bun.file(
37
54
  new URL("../drizzle/0040_colossal_baron_strucker.sql", import.meta.url),
@@ -51,4 +68,41 @@ test("Agent Run 固定不可变 Release 并持久化恢复租约", async () => {
51
68
  expect(bindingMigration).toContain(
52
69
  'CREATE UNIQUE INDEX "uk_agent_run_bindings_token"',
53
70
  );
71
+ const inputCommitmentMigration = await Bun.file(
72
+ new URL("../drizzle/0046_tranquil_living_mummy.sql", import.meta.url),
73
+ ).text();
74
+ expect(inputCommitmentMigration).toContain(
75
+ 'ADD COLUMN "input_digest_commitment"',
76
+ );
77
+ expect(inputCommitmentMigration).toContain(
78
+ "DEFAULT repeat('0', 64) NOT NULL",
79
+ );
80
+ expect(inputCommitmentMigration).toContain(
81
+ 'ALTER COLUMN "input_digest_commitment" DROP DEFAULT',
82
+ );
83
+ const reportMigration = await Bun.file(
84
+ new URL("../drizzle/0045_tiny_cassandra_nova.sql", import.meta.url),
85
+ ).text();
86
+ expect(reportMigration).toContain('CREATE TABLE "agent_runtime_report_runs"');
87
+ expect(reportMigration).toContain(
88
+ 'CREATE TABLE "agent_runtime_report_attempts"',
89
+ );
90
+ expect(reportMigration).toContain(
91
+ 'CREATE UNIQUE INDEX "uk_agent_report_attempts_sequence"',
92
+ );
93
+ expect(reportMigration).toContain(
94
+ 'FOREIGN KEY ("run_id") REFERENCES "public"."agent_runtime_report_runs"',
95
+ );
96
+ const attemptLifecycleMigration = await Bun.file(
97
+ new URL("../drizzle/0047_oval_luke_cage.sql", import.meta.url),
98
+ ).text();
99
+ expect(attemptLifecycleMigration).toContain(
100
+ 'CREATE INDEX "idx_agent_report_attempts_started"',
101
+ );
102
+ expect(attemptLifecycleMigration).toContain(
103
+ `WHERE "outcome" = 'abandoned' AND "finished_at" IS NULL`,
104
+ );
105
+ expect(attemptLifecycleMigration).toContain(
106
+ "'running', 'completed', 'failed', 'cancelled', 'blocked', 'abandoned'",
107
+ );
54
108
  });
@@ -89,6 +89,117 @@ export const agentRuntimeEvents = pgTable(
89
89
  ],
90
90
  );
91
91
 
92
+ export const agentRuntimeReportRuns = pgTable(
93
+ "agent_runtime_report_runs",
94
+ {
95
+ runId: varchar("run_id", { length: 80 }).primaryKey(),
96
+ operationKey: varchar("operation_key", { length: 200 }).notNull(),
97
+ releaseId: varchar("release_id", { length: 80 }).notNull(),
98
+ traceId: varchar("trace_id", { length: 160 }).notNull(),
99
+ actorId: varchar("actor_id", { length: 64 }),
100
+ actorType: varchar("actor_type", { length: 32 }),
101
+ departmentId: varchar("department_id", { length: 64 }),
102
+ status: varchar("status", { length: 32 }).notNull(),
103
+ safeErrorCode: varchar("safe_error_code", { length: 80 }),
104
+ startedAt: doublePrecision("started_at"),
105
+ finishedAt: doublePrecision("finished_at"),
106
+ durationMs: integer("duration_ms"),
107
+ createdAt: doublePrecision("created_at").notNull(),
108
+ updatedAt: doublePrecision("updated_at").notNull(),
109
+ expiresAt: doublePrecision("expires_at").notNull(),
110
+ },
111
+ (table) => [
112
+ index("idx_agent_report_runs_created").on(table.createdAt),
113
+ index("idx_agent_report_runs_status").on(table.status, table.createdAt),
114
+ index("idx_agent_report_runs_operation").on(
115
+ table.operationKey,
116
+ table.createdAt,
117
+ ),
118
+ index("idx_agent_report_runs_actor").on(table.actorId, table.createdAt),
119
+ index("idx_agent_report_runs_department").on(
120
+ table.departmentId,
121
+ table.createdAt,
122
+ ),
123
+ index("idx_agent_report_runs_expiry").on(table.expiresAt),
124
+ check(
125
+ "ck_agent_report_runs_status",
126
+ sql`${table.status} in ('accepted', 'running', 'awaiting-approval', 'completed', 'failed', 'cancelled')`,
127
+ ),
128
+ check(
129
+ "ck_agent_report_runs_duration",
130
+ sql`${table.durationMs} is null or ${table.durationMs} >= 0`,
131
+ ),
132
+ ],
133
+ );
134
+
135
+ export const agentRuntimeReportAttempts = pgTable(
136
+ "agent_runtime_report_attempts",
137
+ {
138
+ attemptId: varchar("attempt_id", { length: 80 }).primaryKey(),
139
+ runId: varchar("run_id", { length: 80 })
140
+ .notNull()
141
+ .references(() => agentRuntimeReportRuns.runId, { onDelete: "cascade" }),
142
+ sequence: integer("sequence").notNull(),
143
+ toolRound: integer("tool_round").notNull(),
144
+ deploymentKey: varchar("deployment_key", { length: 200 }).notNull(),
145
+ requestedModel: varchar("requested_model", { length: 200 }).notNull(),
146
+ reportedModel: varchar("reported_model", { length: 200 }),
147
+ outcome: varchar("outcome", { length: 32 }).notNull(),
148
+ cacheStatus: varchar("cache_status", { length: 16 }).notNull(),
149
+ usageSource: varchar("usage_source", { length: 32 }).notNull(),
150
+ inputTokens: integer("input_tokens"),
151
+ outputTokens: integer("output_tokens"),
152
+ cachedInputTokens: integer("cached_input_tokens"),
153
+ reasoningTokens: integer("reasoning_tokens"),
154
+ totalTokens: integer("total_tokens"),
155
+ firstTokenLatencyMs: integer("first_token_latency_ms"),
156
+ durationMs: integer("duration_ms"),
157
+ safeErrorCode: varchar("safe_error_code", { length: 80 }),
158
+ startedAt: doublePrecision("started_at").notNull(),
159
+ finishedAt: doublePrecision("finished_at"),
160
+ },
161
+ (table) => [
162
+ uniqueIndex("uk_agent_report_attempts_sequence").on(
163
+ table.runId,
164
+ table.sequence,
165
+ ),
166
+ index("idx_agent_report_attempts_model").on(
167
+ table.deploymentKey,
168
+ table.requestedModel,
169
+ table.startedAt,
170
+ ),
171
+ index("idx_agent_report_attempts_outcome").on(
172
+ table.outcome,
173
+ table.startedAt,
174
+ ),
175
+ index("idx_agent_report_attempts_started").on(table.startedAt),
176
+ check("ck_agent_report_attempts_sequence", sql`${table.sequence} > 0`),
177
+ check("ck_agent_report_attempts_tool_round", sql`${table.toolRound} > 0`),
178
+ check(
179
+ "ck_agent_report_attempts_outcome",
180
+ sql`${table.outcome} in ('running', 'completed', 'failed', 'cancelled', 'blocked', 'abandoned')`,
181
+ ),
182
+ check(
183
+ "ck_agent_report_attempts_cache",
184
+ sql`${table.cacheStatus} in ('hit', 'miss', 'unknown')`,
185
+ ),
186
+ check(
187
+ "ck_agent_report_attempts_usage_source",
188
+ sql`${table.usageSource} in ('provider-reported', 'estimated', 'unknown')`,
189
+ ),
190
+ check(
191
+ "ck_agent_report_attempts_non_negative",
192
+ sql`coalesce(${table.inputTokens}, 0) >= 0
193
+ and coalesce(${table.outputTokens}, 0) >= 0
194
+ and coalesce(${table.cachedInputTokens}, 0) >= 0
195
+ and coalesce(${table.reasoningTokens}, 0) >= 0
196
+ and coalesce(${table.totalTokens}, 0) >= 0
197
+ and coalesce(${table.firstTokenLatencyMs}, 0) >= 0
198
+ and coalesce(${table.durationMs}, 0) >= 0`,
199
+ ),
200
+ ],
201
+ );
202
+
92
203
  export const agentEvaluationResults = pgTable(
93
204
  "agent_evaluation_results",
94
205
  {
@@ -127,6 +238,9 @@ export const agentRunBindings = pgTable(
127
238
  actorId: varchar("actor_id", { length: 64 }).notNull(),
128
239
  idempotencyHash: varchar("idempotency_hash", { length: 64 }).notNull(),
129
240
  tokenHash: varchar("token_hash", { length: 64 }).notNull(),
241
+ inputDigestCommitment: varchar("input_digest_commitment", {
242
+ length: 64,
243
+ }).notNull(),
130
244
  scopeHash: varchar("scope_hash", { length: 64 }).notNull(),
131
245
  scopeSnapshot: jsonb("scope_snapshot")
132
246
  .$type<AuthorizationScopeSnapshot>()
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@southwind-ai/jobs",
3
- "version": "0.1.5",
3
+ "version": "0.1.6",
4
4
  "license": "UNLICENSED",
5
5
  "type": "module",
6
6
  "engines": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@southwind-ai/modules",
3
- "version": "0.2.0",
3
+ "version": "0.2.1",
4
4
  "license": "UNLICENSED",
5
5
  "type": "module",
6
6
  "engines": {
@@ -113,6 +113,16 @@ export const systemAdminRoutes: ModuleManifest["adminRoutes"] = [
113
113
  "system.audit",
114
114
  ),
115
115
  // @windy-module system.audit end
116
+ // @windy-module system.agent begin
117
+ route(
118
+ "system.ai-runtime",
119
+ "/admin/system/ai-runtime",
120
+ "AI Runtime 报表",
121
+ "sidebar",
122
+ "system.ai-runtime.read",
123
+ "system.ai-runtime",
124
+ ),
125
+ // @windy-module system.agent end
116
126
  // @windy-module system.operations begin
117
127
  route(
118
128
  "system.ops",
@@ -30,7 +30,7 @@ const definitions = [
30
30
  ["system.storage", []],
31
31
  // @windy-module system.storage end
32
32
  // @windy-module system.agent begin
33
- ["system.agent", []],
33
+ ["system.agent", ["system.ai-runtime"]],
34
34
  // @windy-module system.agent end
35
35
  // @windy-module system.operations begin
36
36
  ["system.operations", ["system.ops"]],
@@ -51,6 +51,22 @@ export function systemControlPlaneApiPermissionBindings(): ApiPermissionBinding[
51
51
 
52
52
  // @windy-module system.agent begin
53
53
  function aiRuntimeBindings(): ApiPermissionBinding[] {
54
+ const reports = (
55
+ [
56
+ ["/api/system/ai-runtime/summary", "agent.runtime.report.read"],
57
+ ["/api/system/ai-runtime/runs", "agent.runtime.report.read"],
58
+ ["/api/system/ai-runtime/runs/:runId", "agent.runtime.run.read"],
59
+ ["/api/system/ai-runtime/actors", "agent.runtime.report.read"],
60
+ ] as const
61
+ ).map(([path, auditAction]) =>
62
+ binding(
63
+ "GET",
64
+ path,
65
+ "system.ai-runtime.read",
66
+ "system.ai-runtime",
67
+ auditAction,
68
+ ),
69
+ );
54
70
  const read = [
55
71
  "/api/internal/ai/artifacts",
56
72
  "/api/document/runs/:runId/events",
@@ -90,7 +106,7 @@ function aiRuntimeBindings(): ApiPermissionBinding[] {
90
106
  path.startsWith("/api/internal/"),
91
107
  ),
92
108
  );
93
- return [...read, ...execute];
109
+ return [...reports, ...read, ...execute];
94
110
  }
95
111
  // @windy-module system.agent end
96
112
 
@@ -86,6 +86,16 @@ export const systemAuditActions: ModuleManifest["auditActions"] = [
86
86
  "agent.mcp.access",
87
87
  "agent.tool.execute",
88
88
  "agent.operation.execute",
89
+ {
90
+ key: "agent.runtime.report.read",
91
+ label: "读取 AI Runtime 报表",
92
+ description: "按当前数据范围读取 Agent Run 聚合、列表或 Actor 目录。",
93
+ },
94
+ {
95
+ key: "agent.runtime.run.read",
96
+ label: "读取 Agent Run 详情",
97
+ description: "按当前数据范围读取单个 Agent Run 与模型 Attempt 计量事实。",
98
+ },
89
99
  // @windy-module system.agent end
90
100
  "security.denied",
91
101
  "system.error",
@@ -98,6 +98,14 @@ export const systemFeatures: ModuleManifest["features"] = [
98
98
  "Agent Tool",
99
99
  "让受控 Agent 在权限、Feature 与审计保护下调用平台工具。",
100
100
  ),
101
+ {
102
+ ...feature(
103
+ "system.ai-runtime",
104
+ "AI Runtime 报表",
105
+ "查看受数据范围约束的 Agent Run、模型用量、缓存与失败事实。",
106
+ ),
107
+ dependencies: [featureKey("system.agent")],
108
+ },
101
109
  // @windy-module system.agent end
102
110
  // @windy-module system.operations begin
103
111
  feature(
@@ -125,6 +125,41 @@ describe("系统能力模块目录", () => {
125
125
  // @windy-module system.data-governance end
126
126
  });
127
127
 
128
+ // @windy-module system.agent begin
129
+ test("AI Runtime 能力与专用审计动作归属 system.agent", () => {
130
+ const agent = systemModuleManifests().find(
131
+ ({ name }) => name === "system.agent",
132
+ );
133
+ const core = systemModuleManifests().find(({ name }) => name === "system");
134
+ const auditKeys = (module: NonNullable<typeof agent>) =>
135
+ module.auditActions.map((action) =>
136
+ typeof action === "string" ? action : action.key,
137
+ );
138
+
139
+ expect(agent?.features.map(({ key }) => key)).toContain(
140
+ "system.ai-runtime",
141
+ );
142
+ expect(agent?.permissions.map(({ key }) => key)).toContain(
143
+ "system.ai-runtime.read",
144
+ );
145
+ expect(agent?.adminRoutes.map(({ key }) => key)).toContain(
146
+ "system.ai-runtime",
147
+ );
148
+ expect(auditKeys(agent!)).toEqual(
149
+ expect.arrayContaining([
150
+ "agent.runtime.report.read",
151
+ "agent.runtime.run.read",
152
+ ]),
153
+ );
154
+ expect(auditKeys(core!)).not.toEqual(
155
+ expect.arrayContaining([
156
+ "agent.runtime.report.read",
157
+ "agent.runtime.run.read",
158
+ ]),
159
+ );
160
+ });
161
+ // @windy-module system.agent end
162
+
128
163
  // @windy-module system.data-governance begin
129
164
  test("能力声明归属到对应模块而不是继续挂在 system 聚合项", () => {
130
165
  const workflow = governanceModuleManifest("system.workflow");
@@ -127,8 +127,8 @@ export const systemModuleDefinitions = [
127
127
  "system.scheduler",
128
128
  "system.workflow",
129
129
  ],
130
- resources: ["agent"],
131
- featureKeys: ["system.agent"],
130
+ resources: ["agent", "ai-runtime"],
131
+ featureKeys: ["system.agent", "system.ai-runtime"],
132
132
  },
133
133
  // @windy-module system.agent end
134
134
  // @windy-module system.operations begin
@@ -293,14 +293,20 @@ function createSystemCapabilityModule(
293
293
  : [],
294
294
  auditActions: isCore
295
295
  ? aggregate.auditActions.filter(
296
- (action) => auditActionKey(action) !== "system.user-directory.query",
296
+ (action) =>
297
+ auditActionKey(action) !== "system.user-directory.query" &&
298
+ !aiRuntimeAuditActions.has(auditActionKey(action)),
297
299
  )
298
300
  : definition.name === "system.identity"
299
301
  ? aggregate.auditActions.filter(
300
302
  (action) =>
301
303
  auditActionKey(action) === "system.user-directory.query",
302
304
  )
303
- : [],
305
+ : definition.name === "system.agent"
306
+ ? aggregate.auditActions.filter((action) =>
307
+ aiRuntimeAuditActions.has(auditActionKey(action)),
308
+ )
309
+ : [],
304
310
  metadata: {
305
311
  kind: "platform-capability",
306
312
  ...(definition.runtimeActivation
@@ -310,6 +316,11 @@ function createSystemCapabilityModule(
310
316
  };
311
317
  }
312
318
 
319
+ const aiRuntimeAuditActions = new Set([
320
+ "agent.runtime.report.read",
321
+ "agent.runtime.run.read",
322
+ ]);
323
+
313
324
  function auditActionKey(
314
325
  action: ModuleManifest["auditActions"][number],
315
326
  ): string {
@@ -60,5 +60,74 @@ describe("系统模块管理面与 MCP 注册", () => {
60
60
  },
61
61
  ]);
62
62
  });
63
+
64
+ test("AI Runtime 报表完整注册 Feature、权限、入口、API 与审计", () => {
65
+ const manifest = systemFoundationModule();
66
+ const menus = manifest.menus.flatMap((menu) => menu.children ?? []);
67
+
68
+ expect(
69
+ manifest.features.find(({ key }) => key === "system.ai-runtime"),
70
+ ).toEqual(
71
+ expect.objectContaining({
72
+ dependencies: ["system.agent"],
73
+ }),
74
+ );
75
+ expect(
76
+ manifest.permissions.find(({ key }) => key === "system.ai-runtime.read"),
77
+ ).toEqual(
78
+ expect.objectContaining({
79
+ resource: "ai-runtime",
80
+ action: "read",
81
+ accessRisk: "sensitive-disclosure",
82
+ }),
83
+ );
84
+ expect(
85
+ manifest.adminRoutes.find(({ key }) => key === "system.ai-runtime"),
86
+ ).toMatchObject({
87
+ path: "/admin/system/ai-runtime",
88
+ permissionKey: "system.ai-runtime.read",
89
+ featureKey: "system.ai-runtime",
90
+ });
91
+ expect(menus.find(({ key }) => key === "system.ai-runtime")).toMatchObject({
92
+ path: "/admin/system/ai-runtime",
93
+ permissionKey: "system.ai-runtime.read",
94
+ featureKey: "system.ai-runtime",
95
+ });
96
+
97
+ const bindings = manifest.apiPermissions.filter(({ path }) =>
98
+ path.startsWith("/api/system/ai-runtime"),
99
+ );
100
+ expect(bindings).toHaveLength(4);
101
+ expect(
102
+ bindings.every(
103
+ ({ method, permissionKey, featureKey }) =>
104
+ method === "GET" &&
105
+ permissionKey === "system.ai-runtime.read" &&
106
+ featureKey === "system.ai-runtime",
107
+ ),
108
+ ).toBe(true);
109
+ expect(bindings).toEqual(
110
+ expect.arrayContaining([
111
+ expect.objectContaining({
112
+ path: "/api/system/ai-runtime/runs/:runId",
113
+ auditAction: "agent.runtime.run.read",
114
+ }),
115
+ expect.objectContaining({
116
+ path: "/api/system/ai-runtime/summary",
117
+ auditAction: "agent.runtime.report.read",
118
+ }),
119
+ ]),
120
+ );
121
+ expect(
122
+ manifest.auditActions.map((action) =>
123
+ typeof action === "string" ? action : action.key,
124
+ ),
125
+ ).toEqual(
126
+ expect.arrayContaining([
127
+ "agent.runtime.report.read",
128
+ "agent.runtime.run.read",
129
+ ]),
130
+ );
131
+ });
63
132
  // @windy-module system.agent end
64
133
  });
@@ -228,6 +228,19 @@ export function systemFoundationModule(): ModuleManifest {
228
228
  featureKey: "system.ops",
229
229
  },
230
230
  // @windy-module system.operations end
231
+ // @windy-module system.agent begin
232
+ {
233
+ key: "system.ai-runtime",
234
+ title: "AI Runtime 报表",
235
+ type: "menu",
236
+ order: 15,
237
+ visible: true,
238
+ path: "/admin/system/ai-runtime",
239
+ icon: "activity",
240
+ permissionKey: "system.ai-runtime.read",
241
+ featureKey: "system.ai-runtime",
242
+ },
243
+ // @windy-module system.agent end
231
244
  // @windy-module system.workflow begin
232
245
  {
233
246
  key: "system.workflow",
@@ -19,6 +19,7 @@ const systemResourceLabels = {
19
19
  license: "许可证管理",
20
20
  audit: "审计日志",
21
21
  agent: "智能代理",
22
+ "ai-runtime": "AI Runtime 报表",
22
23
  ops: "运维总览",
23
24
  scheduler: "定时任务",
24
25
  notification: "通知管理",
@@ -122,6 +123,7 @@ export const systemPermissions: ModuleManifest["permissions"] = [
122
123
  // @windy-module system.audit end
123
124
  // @windy-module system.agent begin
124
125
  permission("agent", "read"),
126
+ permission("ai-runtime", "read", "sensitive-disclosure"),
125
127
  // @windy-module system.agent end
126
128
  // @windy-module system.operations begin
127
129
  permission("ops", "read"),
@@ -17,6 +17,17 @@ export type {
17
17
  ModuleBackgroundAiPort,
18
18
  } from "./src/background-ai-port.js";
19
19
  export { ModuleBackgroundAiError } from "./src/background-ai-port.js";
20
+ export type {
21
+ ModuleDebugSessionContextV1,
22
+ ModuleDebugSessionGetInputV1,
23
+ ModuleDebugSessionListInputV1,
24
+ ModuleDebugSessionMessageV1,
25
+ ModuleDebugSessionPageV1,
26
+ ModuleDebugSessionProviderV1,
27
+ ModuleDebugSessionSummaryV1,
28
+ ModuleDebugSessionV1,
29
+ } from "./src/debug-session-provider.js";
30
+ export { MODULE_DEBUG_SESSION_SCHEMA_VERSION } from "./src/debug-session-provider.js";
20
31
  export type {
21
32
  ModuleAuditEmitter,
22
33
  ModuleAuditEmitInput,
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@southwind-ai/server-sdk",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "license": "UNLICENSED",
5
5
  "type": "module",
6
6
  "engines": {
@@ -15,6 +15,7 @@
15
15
  "src/audit-port.ts",
16
16
  "src/background-ai-port.ts",
17
17
  "src/data-governance-registration.ts",
18
+ "src/debug-session-provider.ts",
18
19
  "src/durable-handler.ts",
19
20
  "src/jobs-port.ts",
20
21
  "src/module-host.ts",
@@ -18,6 +18,11 @@ export interface ModuleAiOperationPort {
18
18
  artifacts?: readonly ModuleAiArtifactRef[];
19
19
  idempotencyKey: string;
20
20
  }): Promise<ModuleAiRunReceipt>;
21
+ verifyAgentRun(input: {
22
+ operationKey: string;
23
+ runId: string;
24
+ input: ModuleAiJsonValue;
25
+ }): Promise<void>;
21
26
  startDocument(input: {
22
27
  operationKey: string;
23
28
  sources: readonly ModuleAiArtifactRef[];
@@ -0,0 +1,63 @@
1
+ import type { ModuleActor } from "./actor.js";
2
+
3
+ export const MODULE_DEBUG_SESSION_SCHEMA_VERSION = 1 as const;
4
+
5
+ export interface ModuleDebugSessionContextV1 {
6
+ readonly actor: ModuleActor;
7
+ readonly operationKey: string;
8
+ readonly signal: AbortSignal;
9
+ }
10
+
11
+ export interface ModuleDebugSessionListInputV1 extends ModuleDebugSessionContextV1 {
12
+ readonly limit: number;
13
+ /** Provider 私有的不透明 keyset cursor;Host 只原样回传给同一 Provider。 */
14
+ readonly cursor?: string;
15
+ }
16
+
17
+ export interface ModuleDebugSessionGetInputV1 extends ModuleDebugSessionContextV1 {
18
+ readonly sourceId: string;
19
+ }
20
+
21
+ export interface ModuleDebugSessionSummaryV1 {
22
+ /** 仅在 Provider 与 Host 之间使用,不会返回给 ADK Web。 */
23
+ readonly sourceId: string;
24
+ readonly title: string;
25
+ readonly scopeLabel?: string;
26
+ readonly updatedAt: string;
27
+ readonly revision: string;
28
+ }
29
+
30
+ export interface ModuleDebugSessionPageV1 {
31
+ readonly sessions: readonly ModuleDebugSessionSummaryV1[];
32
+ readonly truncated: boolean;
33
+ /** truncated=true 时必须提供,用于 Host 继续读取直到完整。 */
34
+ readonly next?: string;
35
+ }
36
+
37
+ export interface ModuleDebugSessionMessageV1 {
38
+ readonly sequence: number;
39
+ readonly role: "user" | "assistant";
40
+ readonly content: string;
41
+ readonly createdAt: string;
42
+ }
43
+
44
+ export interface ModuleDebugSessionV1 extends ModuleDebugSessionSummaryV1 {
45
+ readonly messages: readonly ModuleDebugSessionMessageV1[];
46
+ }
47
+
48
+ /**
49
+ * 开发期 ADK Web 会话投影。Provider 只读业务事实,Host 负责重新授权、审计、
50
+ * 有界校验与不透明 ID;V1 不支持业务会话的追加、重命名或删除。
51
+ */
52
+ export interface ModuleDebugSessionProviderV1 {
53
+ readonly schemaVersion: typeof MODULE_DEBUG_SESSION_SCHEMA_VERSION;
54
+ readonly key: string;
55
+ readonly operationKeys: readonly string[];
56
+ readonly featureKey: string;
57
+ readonly permissionKey: string;
58
+ readonly auditAction: string;
59
+ list(input: ModuleDebugSessionListInputV1): Promise<ModuleDebugSessionPageV1>;
60
+ get(
61
+ input: ModuleDebugSessionGetInputV1,
62
+ ): Promise<ModuleDebugSessionV1 | undefined>;
63
+ }