@nekro-nxt/contracts 0.4.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/README.md +2 -0
  2. package/dist/index.mjs +3092 -164
  3. package/dist/index.mjs.map +1 -1
  4. package/lib/types/commands.d.ts +408 -0
  5. package/lib/types/commands.d.ts.map +1 -0
  6. package/lib/types/community-feedback-host.d.ts +442 -0
  7. package/lib/types/community-feedback-host.d.ts.map +1 -0
  8. package/lib/types/community-feedback.d.ts +1072 -0
  9. package/lib/types/community-feedback.d.ts.map +1 -0
  10. package/lib/types/community-personas.d.ts +4 -0
  11. package/lib/types/community-personas.d.ts.map +1 -1
  12. package/lib/types/community.d.ts +260 -13
  13. package/lib/types/community.d.ts.map +1 -1
  14. package/lib/types/config-schema.d.ts +16 -2
  15. package/lib/types/config-schema.d.ts.map +1 -1
  16. package/lib/types/credentials.d.ts +328 -0
  17. package/lib/types/credentials.d.ts.map +1 -0
  18. package/lib/types/domain.d.ts +44 -2
  19. package/lib/types/domain.d.ts.map +1 -1
  20. package/lib/types/extension-capabilities.d.ts +58 -3
  21. package/lib/types/extension-capabilities.d.ts.map +1 -1
  22. package/lib/types/extension-ui.d.ts +46 -4
  23. package/lib/types/extension-ui.d.ts.map +1 -1
  24. package/lib/types/host-api.d.ts +10805 -2887
  25. package/lib/types/host-api.d.ts.map +1 -1
  26. package/lib/types/index.d.ts +7 -0
  27. package/lib/types/index.d.ts.map +1 -1
  28. package/lib/types/linked-accounts.d.ts +100 -0
  29. package/lib/types/linked-accounts.d.ts.map +1 -0
  30. package/lib/types/logs.d.ts +355 -0
  31. package/lib/types/logs.d.ts.map +1 -0
  32. package/lib/types/response-timing.d.ts +60 -0
  33. package/lib/types/response-timing.d.ts.map +1 -0
  34. package/lib/types/runtime-compatibility.d.ts +2 -2
  35. package/package.json +1 -1
  36. package/src/commands.ts +366 -0
  37. package/src/community-feedback-host.ts +121 -0
  38. package/src/community-feedback.ts +289 -0
  39. package/src/community.ts +63 -1
  40. package/src/config-schema.ts +33 -2
  41. package/src/credentials.ts +260 -0
  42. package/src/domain.ts +74 -8
  43. package/src/extension-capabilities.ts +78 -4
  44. package/src/extension-ui.ts +3 -0
  45. package/src/host-api.ts +1873 -163
  46. package/src/index.ts +8 -0
  47. package/src/linked-accounts.ts +77 -0
  48. package/src/logs.ts +138 -0
  49. package/src/management-api.ts +1 -1
  50. package/src/response-timing.ts +77 -0
package/src/index.ts CHANGED
@@ -5,5 +5,13 @@ export * from './host-api.js'
5
5
  export * from './management-api.js'
6
6
  export * from './runtime-compatibility.js'
7
7
  export * from './extension-capabilities.js'
8
+ export * from './credentials.js'
9
+ export * from './linked-accounts.js'
8
10
  export * from './community.js'
9
11
  export * from './community-personas.js'
12
+
13
+ export * from './commands.js'
14
+ export * from './logs.js'
15
+ export * from './community-feedback.js'
16
+ export * from './community-feedback-host.js'
17
+ export * from './response-timing.js'
@@ -0,0 +1,77 @@
1
+ import { z } from 'zod'
2
+ import { AgentIdSchema, ChannelIdSchema, LinkedAccountIdSchema } from './domain.js'
3
+
4
+ /**
5
+ * Linked accounts (设置 → 关联账号): third-party accounts that agents' commands act as. The library only keeps them;
6
+ * an agent's commands receive an account only through its `commandAccounts` grant (命令账号授权 A1、A2). Tokens are
7
+ * write-only; every view below carries metadata only.
8
+ */
9
+
10
+ /** Platforms the host can link accounts of; each grant names one account per platform. */
11
+ export const LinkedAccountPlatformIdSchema = z.enum(['github'])
12
+ export type LinkedAccountPlatformId = z.output<typeof LinkedAccountPlatformIdSchema>
13
+
14
+ /** How an account is added: a typed token, or the token of a login the platform's local CLI holds (read once). */
15
+ export const LinkedAccountMethodSchema = z.enum(['token', 'gh-login'])
16
+ export type LinkedAccountMethod = z.output<typeof LinkedAccountMethodSchema>
17
+
18
+ /** A login the local `gh` holds, offered as a quick way to link a GitHub account. */
19
+ export const LocalGithubLoginSchema = z.object({ login: z.string().trim().min(1), active: z.boolean() }).strict()
20
+
21
+ const tokenFields = { method: z.literal('token'), token: z.string().trim().min(1).max(512) }
22
+ const ghLoginFields = { method: z.literal('gh-login'), login: z.string().trim().min(1).max(128) }
23
+
24
+ /** Where a token comes from: typed, or read once from a login of the platform's local CLI. */
25
+ export const LinkedAccountTokenSourceSchema = z.discriminatedUnion('method', [
26
+ z.object(tokenFields).strict(),
27
+ z.object(ghLoginFields).strict(),
28
+ ])
29
+ export type LinkedAccountTokenSource = z.output<typeof LinkedAccountTokenSourceSchema>
30
+
31
+ export const LinkedAccountViewSchema = z
32
+ .object({
33
+ id: LinkedAccountIdSchema,
34
+ platform: LinkedAccountPlatformIdSchema,
35
+ /** The account name on the platform, as the platform reported it when the token was verified. */
36
+ login: z.string(),
37
+ /** Token scopes where the platform reports them (GitHub classic tokens); `null` otherwise. */
38
+ scopes: z.array(z.string()).nullable(),
39
+ source: LinkedAccountMethodSchema,
40
+ /** False when the stored token cannot be read any more; the account stays so it can be replaced or removed. */
41
+ available: z.boolean(),
42
+ /** Agents whose capabilities grant this account. */
43
+ grantedAgentIds: z.array(AgentIdSchema),
44
+ createdAt: z.number().int().nonnegative(),
45
+ updatedAt: z.number().int().nonnegative(),
46
+ lastUsedAt: z.number().int().nonnegative().nullable(),
47
+ })
48
+ .strict()
49
+ export type LinkedAccountView = z.output<typeof LinkedAccountViewSchema>
50
+
51
+ /** Links an account: the platform plus how its token is given. */
52
+ export const AddLinkedAccountRequestSchema = z.discriminatedUnion('method', [
53
+ z.object({ platform: LinkedAccountPlatformIdSchema, ...tokenFields }).strict(),
54
+ z.object({ platform: LinkedAccountPlatformIdSchema, ...ghLoginFields }).strict(),
55
+ ])
56
+ export type AddLinkedAccountRequest = z.output<typeof AddLinkedAccountRequestSchema>
57
+
58
+ /** A new token for an account; it must belong to the same account on the platform. */
59
+ export const ReplaceLinkedAccountTokenRequestSchema = LinkedAccountTokenSourceSchema
60
+ export type ReplaceLinkedAccountTokenRequest = z.output<typeof ReplaceLinkedAccountTokenRequestSchema>
61
+
62
+ /** Removing a granted account needs `confirm`; without it the result lists the agents it is granted to. */
63
+ export const RemoveLinkedAccountRequestSchema = z.object({ confirm: z.boolean().default(false) }).strict()
64
+
65
+ /** One recorded use: an agent's command environment carried the account. Newest 500 per account, none over 90 days. */
66
+ export const LinkedAccountUseSchema = z
67
+ .object({
68
+ at: z.number().int().nonnegative(),
69
+ agentId: AgentIdSchema.nullable(),
70
+ channelId: ChannelIdSchema.nullable(),
71
+ consumerKind: z.enum(['command']),
72
+ consumerId: z.string(),
73
+ })
74
+ .strict()
75
+ export type LinkedAccountUse = z.output<typeof LinkedAccountUseSchema>
76
+
77
+ export const LinkedAccountUsesViewSchema = z.object({ uses: z.array(LinkedAccountUseSchema) }).strict()
package/src/logs.ts ADDED
@@ -0,0 +1,138 @@
1
+ import { z } from 'zod'
2
+
3
+ /** Log summaries are labels; leave structured diagnostics and stacks untouched. */
4
+ export function formatLogMessage(message: string): string {
5
+ return message.trimEnd().replace(/[。.]$/u, '')
6
+ }
7
+
8
+ export const hostLogLevelSchema = z.enum(['debug', 'info', 'warn', 'error'])
9
+ export type HostLogLevel = z.infer<typeof hostLogLevelSchema>
10
+ /** Write-only, owner-bound SDK capability. No caller-supplied identity fields. */
11
+ export interface NxtLogger {
12
+ debug(message: string, details?: unknown): void
13
+ info(message: string, details?: unknown): void
14
+ warn(message: string, details?: unknown): void
15
+ error(message: string, details?: unknown): void
16
+ }
17
+ export const hostLogSourceKindSchema = z.enum(['system', 'dsh-plugin', 'extension', 'connection', 'unknown'])
18
+ export type HostLogSourceKind = z.infer<typeof hostLogSourceKindSchema>
19
+ export const hostLogSourceSchema = z
20
+ .object({
21
+ kind: hostLogSourceKindSchema,
22
+ id: z.string().min(1).max(512),
23
+ name: z.string().min(1).max(512),
24
+ version: z.string().max(512).optional(),
25
+ component: z.string().max(512).optional(),
26
+ })
27
+ .strict()
28
+ export type HostLogSource = z.infer<typeof hostLogSourceSchema>
29
+ export const hostLogScopeSchema = z
30
+ .object({
31
+ extensionId: z.string().max(512).optional(),
32
+ revisionId: z.string().max(512).optional(),
33
+ connectionId: z.string().max(512).optional(),
34
+ agentId: z.string().max(512).optional(),
35
+ channelId: z.string().max(512).optional(),
36
+ sessionId: z.string().max(512).optional(),
37
+ episodeId: z.string().max(512).optional(),
38
+ operationId: z.string().max(512).optional(),
39
+ })
40
+ .strict()
41
+ export type HostLogScope = z.infer<typeof hostLogScopeSchema>
42
+ export const hostLogEntrySchema = z
43
+ .object({
44
+ id: z.string(),
45
+ sequence: z.number().int().nonnegative(),
46
+ timestamp: z.iso.datetime(),
47
+ runId: z.string(),
48
+ level: hostLogLevelSchema,
49
+ message: z.string(),
50
+ source: hostLogSourceSchema,
51
+ scope: hostLogScopeSchema.optional(),
52
+ details: z.json().optional(),
53
+ code: z.string().optional(),
54
+ redacted: z.boolean(),
55
+ truncated: z.boolean(),
56
+ })
57
+ .strict()
58
+ export type HostLogEntry = z.infer<typeof hostLogEntrySchema>
59
+ export interface HostLogInput {
60
+ formatArgs?: readonly unknown[]
61
+ level: HostLogLevel
62
+ message: string
63
+ source: HostLogSource
64
+ scope?: HostLogScope
65
+ details?: unknown
66
+ code?: string
67
+ }
68
+ export const hostLogQuerySchema = z
69
+ .object({
70
+ levels: z.array(hostLogLevelSchema).max(4).optional(),
71
+ sourceKinds: z.array(hostLogSourceKindSchema).max(5).optional(),
72
+ sourceIds: z.array(z.string().max(512)).max(100).optional(),
73
+ sources: z
74
+ .array(hostLogSourceSchema.pick({ kind: true, id: true }))
75
+ .max(100)
76
+ .optional(),
77
+ scope: hostLogScopeSchema.optional(),
78
+ keyword: z.string().max(1000).optional(),
79
+ from: z.iso.datetime().optional(),
80
+ to: z.iso.datetime().optional(),
81
+ olderCursor: z.string().max(128).optional(),
82
+ afterCursor: z.string().max(128).optional(),
83
+ headCursor: z.string().max(128).optional(),
84
+ limit: z.number().int().min(1).max(500).optional(),
85
+ })
86
+ .strict()
87
+ export type HostLogQuery = z.infer<typeof hostLogQuerySchema>
88
+ export const hostLogPageSchema = z
89
+ .object({
90
+ entries: z.array(hostLogEntrySchema),
91
+ olderCursor: z.string().nullable(),
92
+ headCursor: z.string(),
93
+ hasMore: z.boolean(),
94
+ gap: z.enum(['expired', 'reset']).optional(),
95
+ })
96
+ .strict()
97
+ export type HostLogPage = z.infer<typeof hostLogPageSchema>
98
+ export const hostLogSettingsSchema = z
99
+ .object({
100
+ retentionDays: z.number().int().min(1).max(30),
101
+ maxSizeMiB: z.number().int().min(64).max(2048),
102
+ revision: z.number().int().nonnegative(),
103
+ })
104
+ .strict()
105
+ export type HostLogSettings = z.infer<typeof hostLogSettingsSchema>
106
+ export const hostLogSettingsUpdateSchema = hostLogSettingsSchema
107
+ export const hostLogDebugRequestSchema = z
108
+ .object({
109
+ source: hostLogSourceSchema.pick({ kind: true, id: true }).optional(),
110
+ durationMinutes: z.union([z.literal(5), z.literal(15), z.literal(30)]).default(15),
111
+ })
112
+ .strict()
113
+ export type HostLogDebugRequest = z.infer<typeof hostLogDebugRequestSchema>
114
+ export const hostLogDebugLeaseSchema = hostLogDebugRequestSchema.extend({ id: z.string(), expiresAt: z.iso.datetime() })
115
+ export type HostLogDebugLease = z.infer<typeof hostLogDebugLeaseSchema>
116
+ export const hostLogStatusSchema = z
117
+ .object({
118
+ state: z.enum(['ready', 'degraded', 'closed']),
119
+ runId: z.string(),
120
+ headCursor: z.string(),
121
+ bytes: z.number().nonnegative(),
122
+ count: z.number().int().nonnegative(),
123
+ oldestTimestamp: z.iso.datetime().nullable(),
124
+ newestTimestamp: z.iso.datetime().nullable(),
125
+ queuedBytes: z.number().nonnegative(),
126
+ droppedCount: z.number().int().nonnegative(),
127
+ debugLeases: z.array(hostLogDebugLeaseSchema),
128
+ error: z.string().optional(),
129
+ })
130
+ .strict()
131
+ export type HostLogStatus = z.infer<typeof hostLogStatusSchema>
132
+ export const hostLogStreamEventSchema = z.discriminatedUnion('type', [
133
+ z.object({ type: z.literal('entries'), entries: z.array(hostLogEntrySchema), cursor: z.string() }),
134
+ z.object({ type: z.literal('gap'), reason: z.enum(['expired', 'reset', 'overflow']), cursor: z.string() }),
135
+ z.object({ type: z.literal('status'), status: hostLogStatusSchema }),
136
+ ])
137
+ export type HostLogStreamEvent = z.infer<typeof hostLogStreamEventSchema>
138
+ export type HostLogExportFormat = 'text' | 'jsonl'
@@ -124,7 +124,7 @@ export const ClientNotificationSchema = z
124
124
  route: z
125
125
  .string()
126
126
  .regex(
127
- /^\/(?:(?:live|channels|agents|workshop|wiring|settings|apps|work|connections|users|extensions)(?:\/[^?#]*)?)?$/u,
127
+ /^\/(?:(?:live|channels|agents|workshop|wiring|settings|community|apps|work|connections|users|extensions)(?:\/[^?#]*)?)?(?:\?[^#]*)?$/u,
128
128
  )
129
129
  .optional(),
130
130
  })
@@ -0,0 +1,77 @@
1
+ import { z } from 'zod'
2
+
3
+ /** Bounds of the numeric response timing settings; the host rejects values outside them. */
4
+ export const RESPONSE_TIMING_LIMITS = {
5
+ waitMaxQuietSeconds: { min: 5, max: 300 },
6
+ waitMaxTotalSeconds: { min: 10, max: 900 },
7
+ debounceSeconds: { min: 0, max: 30 },
8
+ debounceMaxSeconds: { min: 1, max: 120 },
9
+ debounceMaxMessages: { min: 1, max: 20 },
10
+ attentionSeconds: { min: 5, max: 600 },
11
+ midWakesPerMinute: { min: 1, max: 30 },
12
+ } as const
13
+
14
+ const bounded = (key: keyof typeof RESPONSE_TIMING_LIMITS) =>
15
+ z.number().int().min(RESPONSE_TIMING_LIMITS[key].min).max(RESPONSE_TIMING_LIMITS[key].max).optional()
16
+
17
+ /**
18
+ * Per-binding timing of when the agent speaks (Decision 2026-10-31 响应时机与智能响应). Every field is optional: an
19
+ * omitted one uses {@link RESPONSE_TIMING_DEFAULTS}. Waiting applies to every policy that answers messages; the rest
20
+ * only to `smart`.
21
+ */
22
+ export const ResponseTimingSettingsSchema = z
23
+ .object({
24
+ /** The agent may end a turn with `waiting-for-more` and be woken when the speaker goes quiet. */
25
+ waitEnabled: z.boolean().optional(),
26
+ /** Longest quiet period one wait may ask for. */
27
+ waitMaxQuietSeconds: bounded('waitMaxQuietSeconds'),
28
+ /** Longest the agent may keep waiting for one person, counted from the first wait. */
29
+ waitMaxTotalSeconds: bounded('waitMaxTotalSeconds'),
30
+ /** Smart: wait for the speaker to stay quiet this long before a turn starts; 0 starts at once. */
31
+ debounceSeconds: bounded('debounceSeconds'),
32
+ /** Smart: start anyway once this long has passed since the first message. */
33
+ debounceMaxSeconds: bounded('debounceMaxSeconds'),
34
+ /** Smart: start anyway once this many messages from the speaker are collected. */
35
+ debounceMaxMessages: bounded('debounceMaxMessages'),
36
+ /** Smart: a message that contains the agent's name or an alias wakes it. */
37
+ nameWake: z.boolean().optional(),
38
+ /** Smart: after someone talks with the agent, their next messages wake it for a while. */
39
+ attentionWake: z.boolean().optional(),
40
+ attentionSeconds: bounded('attentionSeconds'),
41
+ /** Smart: name and attention wakes per channel per minute; strong signals are never limited. */
42
+ midWakesPerMinute: bounded('midWakesPerMinute'),
43
+ })
44
+ .strict()
45
+
46
+ export type ResponseTimingSettings = z.infer<typeof ResponseTimingSettingsSchema>
47
+
48
+ export type ResolvedResponseTiming = {
49
+ readonly [K in keyof ResponseTimingSettings]-?: NonNullable<ResponseTimingSettings[K]>
50
+ }
51
+
52
+ export const RESPONSE_TIMING_DEFAULTS: ResolvedResponseTiming = {
53
+ waitEnabled: true,
54
+ waitMaxQuietSeconds: 60,
55
+ waitMaxTotalSeconds: 120,
56
+ debounceSeconds: 3,
57
+ debounceMaxSeconds: 30,
58
+ debounceMaxMessages: 5,
59
+ nameWake: true,
60
+ attentionWake: true,
61
+ attentionSeconds: 60,
62
+ midWakesPerMinute: 3,
63
+ }
64
+
65
+ /** Shortest quiet period a wait may ask for, whatever the channel allows. */
66
+ export const RESPONSE_WAIT_MIN_QUIET_SECONDS = 5
67
+
68
+ export const resolveResponseTiming = (settings: ResponseTimingSettings | undefined): ResolvedResponseTiming => ({
69
+ ...RESPONSE_TIMING_DEFAULTS,
70
+ ...Object.fromEntries(Object.entries(settings ?? {}).filter(([, value]) => value !== undefined)),
71
+ })
72
+
73
+ /** Extra names that wake the agent in smart mode; the display name always counts too. */
74
+ export const AgentAliasesSchema = z
75
+ .array(z.string().trim().min(1).max(32))
76
+ .max(16)
77
+ .transform((aliases) => [...new Set(aliases)])