@meistrari/agent-core 0.2.0-experimental.0 → 0.2.0-experimental.2

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 (90) hide show
  1. package/README.md +82 -0
  2. package/docs/consumer-capability-matrix.md +374 -0
  3. package/package.json +17 -10
  4. package/scripts/generate-codex-protocol.ts +711 -0
  5. package/src/agents/agent-operation.ts +8 -0
  6. package/src/agents/agent-provider.ts +3 -0
  7. package/src/agents/agent-run.ts +14 -2
  8. package/src/agents/agent-runtime-error.ts +28 -0
  9. package/src/agents/agent-session-events.ts +33 -0
  10. package/src/agents/agent-tool-runner.ts +12 -11
  11. package/src/agents/agent-tool.ts +12 -4
  12. package/src/agents/author-context.ts +1 -1
  13. package/src/agents/claude/claude-auth.ts +40 -0
  14. package/src/agents/claude/claude-browser-turn-metadata.ts +70 -0
  15. package/src/agents/claude/claude-code-process.ts +98 -0
  16. package/src/agents/claude/claude-command-mapper.ts +63 -3
  17. package/src/agents/claude/claude-desktop.ts +55 -0
  18. package/src/agents/claude/claude-event-mapper.ts +876 -124
  19. package/src/agents/claude/claude-file-change.ts +128 -0
  20. package/src/agents/claude/claude-provider.ts +344 -29
  21. package/src/agents/claude/claude-run.ts +922 -91
  22. package/src/agents/claude/claude-selected-repository-instructions.ts +91 -0
  23. package/src/agents/claude/claude-skill-catalog.ts +75 -0
  24. package/src/agents/claude/claude-steered-notifications.ts +180 -0
  25. package/src/agents/claude/claude-tool-mapper.ts +81 -2
  26. package/src/agents/claude/claude-workspace-skills.ts +87 -0
  27. package/src/agents/claude/index.ts +2 -0
  28. package/src/agents/codex/codex-auth-mapper.ts +27 -0
  29. package/src/agents/codex/codex-auth.ts +19 -0
  30. package/src/agents/codex/codex-browser-auth-broker.ts +320 -0
  31. package/src/agents/codex/codex-browser-auth-status.ts +55 -0
  32. package/src/agents/codex/codex-command-mapper.ts +38 -3
  33. package/src/agents/codex/codex-event-mapper.ts +375 -64
  34. package/src/agents/codex/codex-json-rpc-client.ts +66 -21
  35. package/src/agents/codex/codex-provider.ts +118 -236
  36. package/src/agents/codex/codex-run-auth.ts +113 -0
  37. package/src/agents/codex/codex-run.ts +428 -48
  38. package/src/agents/codex/codex-tool-mapper.ts +2 -2
  39. package/src/agents/codex/codex.errors.ts +8 -0
  40. package/src/agents/codex/generated/meta.gen.ts +144 -6
  41. package/src/agents/codex/generated/namespaces.gen.ts +92 -3
  42. package/src/agents/codex/generated/schema.gen.ts +24698 -15638
  43. package/src/agents/codex/lazy-codex-run-auth.ts +47 -0
  44. package/src/agents/index.ts +5 -0
  45. package/src/agents/input-attachment-preparation.ts +13 -0
  46. package/src/agents/mcp-tool-content.ts +82 -0
  47. package/src/agents/model-rebinding-run.ts +14 -3
  48. package/src/agents/selected-repository-instructions.ts +202 -0
  49. package/src/agents/session-context.ts +41 -0
  50. package/src/agents/subscription-token-refresh.ts +73 -0
  51. package/src/agents/user-input-request.ts +19 -20
  52. package/src/errors/index.ts +1 -1
  53. package/src/errors/validation-error.ts +6 -0
  54. package/src/protocol/agent-catalog.ts +159 -0
  55. package/src/protocol/agent-command.ts +54 -7
  56. package/src/protocol/agent-content.ts +36 -16
  57. package/src/protocol/agent-event.ts +210 -73
  58. package/src/protocol/agent-identity.ts +29 -0
  59. package/src/protocol/agent-json.ts +122 -8
  60. package/src/protocol/agent-metadata.ts +2 -2
  61. package/src/protocol/agent-model.ts +13 -1
  62. package/src/protocol/agent-notification.ts +110 -0
  63. package/src/protocol/agent-presentation.ts +71 -20
  64. package/src/protocol/agent-tool.ts +66 -10
  65. package/src/protocol/agent-usage.ts +4 -1
  66. package/src/protocol/agent-user-input.ts +4 -4
  67. package/src/protocol/agent-work.ts +12 -10
  68. package/src/protocol/index.ts +2 -0
  69. package/src/protocol/rejected-keys.ts +11 -0
  70. package/src/provenance.gen.ts +3 -3
  71. package/src/steps/contract.ts +4 -1
  72. package/src/steps/projector.ts +17 -1
  73. package/src/supervisor/agent-provider-factory.ts +60 -5
  74. package/src/supervisor/bootstrap-binder.ts +3 -2
  75. package/src/supervisor/index.ts +1 -1
  76. package/src/supervisor/persistence/supervisor-store.ts +22 -8
  77. package/src/supervisor/runtime-handler.ts +30 -2
  78. package/src/supervisor-protocol/agent-event-wrapper.ts +30 -0
  79. package/src/supervisor-protocol/bootstrap.ts +4 -1
  80. package/src/supervisor-protocol/command-body.ts +4 -1
  81. package/src/supervisor-protocol/envelopes/supervisor-to-control-plane.ts +1 -0
  82. package/src/testing/in-memory-runtime-control-plane.ts +118 -12
  83. package/src/testing/index.ts +1 -1
  84. package/src/worker-runtime-client/command-pump.ts +85 -10
  85. package/src/worker-runtime-client/connection-attempt.ts +95 -20
  86. package/src/worker-runtime-client/frame-processor.ts +242 -58
  87. package/src/worker-runtime-client/index.ts +8 -2
  88. package/src/worker-runtime-client/ports.ts +34 -2
  89. package/src/worker-runtime-client/rpc-request-manager.ts +152 -107
  90. package/src/worker-runtime-client/sandbox-connection-runtime.ts +72 -35
@@ -0,0 +1,159 @@
1
+ import type { AgentReasoningEffort } from './agent-command'
2
+ import type { AgentModelPresentation } from './agent-presentation'
3
+ import type { AgentProviderId } from './agent-provider'
4
+ import z from 'zod'
5
+ import { agentReasoningEffortSchema } from './agent-command'
6
+ import { claudeModelIds, claudeModelIdSchema, codexModelIds, codexModelIdSchema } from './agent-model'
7
+ import { claudeModelPresentation, codexModelPresentation } from './agent-presentation'
8
+
9
+ /**
10
+ * The product catalog of agent harnesses and the models users may select for each.
11
+ * Every creation surface (API, Web, CLI, Slack assistant) reads its choices and defaults
12
+ * from here. The wire model unions in `agent-model.ts` stay broader so historical ids in
13
+ * stored events keep parsing; creation accepts only the selectable ids below.
14
+ *
15
+ * "Harness" is display vocabulary only: code and the public API keep `provider`.
16
+ */
17
+ export const selectableCodexModelIds = codexModelIds
18
+
19
+ /** Verified available to the configured Claude subscription through `supportedModels()`. */
20
+ export const selectableClaudeModelIds = [
21
+ 'claude-opus-5-5',
22
+ 'claude-sonnet-5',
23
+ 'claude-fable-5-1',
24
+ ] as const
25
+
26
+ export type SelectableCodexModelId = typeof selectableCodexModelIds[number]
27
+ export type SelectableClaudeModelId = typeof selectableClaudeModelIds[number]
28
+
29
+ export interface SelectableAgentModelIdByProvider {
30
+ codex: SelectableCodexModelId
31
+ claude: SelectableClaudeModelId
32
+ }
33
+
34
+ export type SelectableAgentModelId<Provider extends AgentProviderId = AgentProviderId> = SelectableAgentModelIdByProvider[Provider]
35
+
36
+ export interface AgentHarness<Provider extends AgentProviderId> {
37
+ provider: Provider
38
+ label: string
39
+ /** Picker order. */
40
+ models: readonly SelectableAgentModelId<Provider>[]
41
+ defaultModel: SelectableAgentModelId<Provider>
42
+ modelPresentation: Record<SelectableAgentModelId<Provider>, AgentModelPresentation>
43
+ }
44
+
45
+ export const agentHarnesses: { readonly [Provider in AgentProviderId]: AgentHarness<Provider> } = {
46
+ codex: {
47
+ provider: 'codex',
48
+ label: 'Codex',
49
+ models: selectableCodexModelIds,
50
+ defaultModel: 'gpt-6-astra',
51
+ modelPresentation: codexModelPresentation,
52
+ },
53
+ claude: {
54
+ provider: 'claude',
55
+ label: 'Claude',
56
+ models: selectableClaudeModelIds,
57
+ defaultModel: 'claude-opus-5-5',
58
+ modelPresentation: claudeModelPresentation,
59
+ },
60
+ }
61
+
62
+ /** Picker order for harnesses. */
63
+ export const agentHarnessOrder = ['codex', 'claude'] as const satisfies readonly AgentProviderId[]
64
+
65
+ const codexAgentSelectionSchema = z.strictObject({
66
+ provider: z.literal('codex'),
67
+ model: z.enum(selectableCodexModelIds),
68
+ reasoningEffort: agentReasoningEffortSchema,
69
+ })
70
+
71
+ const claudeAgentSelectionSchema = z.strictObject({
72
+ provider: z.literal('claude'),
73
+ model: z.enum(selectableClaudeModelIds),
74
+ reasoningEffort: agentReasoningEffortSchema,
75
+ })
76
+
77
+ /** A complete initial agent selection: harness, a model of that harness, and an effort. */
78
+ export const agentSelectionSchema = z.discriminatedUnion('provider', [
79
+ codexAgentSelectionSchema,
80
+ claudeAgentSelectionSchema,
81
+ ])
82
+
83
+ export type AgentSelection = z.infer<typeof agentSelectionSchema>
84
+
85
+ /**
86
+ * An agent selection recorded earlier: a provisioned session, a queued job, or a published
87
+ * event. It accepts every wire model id of its harness so a record keeps parsing after its
88
+ * model leaves the selectable catalog. New selections validate with `agentSelectionSchema`.
89
+ */
90
+ export const storedAgentSelectionSchema = z.discriminatedUnion('provider', [
91
+ z.strictObject({
92
+ provider: z.literal('codex'),
93
+ model: codexModelIdSchema,
94
+ reasoningEffort: agentReasoningEffortSchema,
95
+ }),
96
+ z.strictObject({
97
+ provider: z.literal('claude'),
98
+ model: claudeModelIdSchema,
99
+ reasoningEffort: agentReasoningEffortSchema,
100
+ }),
101
+ ])
102
+
103
+ export type StoredAgentSelection = z.infer<typeof storedAgentSelectionSchema>
104
+
105
+ const wireModelIdsByProvider: { readonly [Provider in AgentProviderId]: ReadonlySet<string> } = {
106
+ codex: new Set<string>(codexModelIds),
107
+ claude: new Set<string>(claudeModelIds),
108
+ }
109
+
110
+ /**
111
+ * The harness whose wire model ids include `model`, including ids no longer selectable.
112
+ * Use it to resolve a recorded selection; new selections use `agentHarnessForModel`.
113
+ */
114
+ export function storedAgentHarnessForModel(model: string): AgentProviderId | undefined {
115
+ return agentHarnessOrder.find(provider => wireModelIdsByProvider[provider].has(model))
116
+ }
117
+
118
+ export const defaultAgentSelection = {
119
+ provider: 'codex',
120
+ model: 'gpt-6-astra',
121
+ reasoningEffort: 'medium',
122
+ } as const satisfies AgentSelection
123
+
124
+ const selectableModelIdsByProvider: { readonly [Provider in AgentProviderId]: ReadonlySet<string> } = {
125
+ codex: new Set<string>(selectableCodexModelIds),
126
+ claude: new Set<string>(selectableClaudeModelIds),
127
+ }
128
+
129
+ /** The harness that offers a selectable model id, or undefined for an unselectable id. */
130
+ export function agentHarnessForModel(model: string): AgentProviderId | undefined {
131
+ return agentHarnessOrder.find(provider => isSelectableAgentModel(provider, model))
132
+ }
133
+
134
+ export function isSelectableAgentModel<Provider extends AgentProviderId>(
135
+ provider: Provider,
136
+ model: string,
137
+ ): model is SelectableAgentModelId<Provider> {
138
+ return selectableModelIdsByProvider[provider].has(model)
139
+ }
140
+
141
+ const selectableModelPresentationById: ReadonlyMap<string, AgentModelPresentation> = new Map([
142
+ ...selectableCodexModelIds.map(model => [model, codexModelPresentation[model]] as const),
143
+ ...selectableClaudeModelIds.map(model => [model, claudeModelPresentation[model]] as const),
144
+ ])
145
+
146
+ /** Presentation for a selectable model id of any harness; undefined for historical or unknown ids. */
147
+ export function selectableAgentModelPresentation(model: string): AgentModelPresentation | undefined {
148
+ return selectableModelPresentationById.get(model)
149
+ }
150
+
151
+ /**
152
+ * The complete selection for a selectable model id of any harness at the given effort, or
153
+ * undefined when no harness offers the model. Pickers that list every harness's models
154
+ * together use this to derive the harness from the chosen model.
155
+ */
156
+ export function agentSelectionForModel(model: string, reasoningEffort: AgentReasoningEffort): AgentSelection | undefined {
157
+ const parsed = agentSelectionSchema.safeParse({ provider: agentHarnessForModel(model), model, reasoningEffort })
158
+ return parsed.success ? parsed.data : undefined
159
+ }
@@ -1,67 +1,114 @@
1
1
  import z from 'zod'
2
2
  import { agentPromptSchema } from './agent-content'
3
+ import { agentModelIdSchema } from './agent-model'
4
+ import { agentNotificationInstructionSchema, agentNotificationsSchema, isAgentNotificationToolOutputWithinSizeLimit } from './agent-notification'
3
5
  import { agentProviderIdSchema } from './agent-provider'
4
6
  import { agentUserInputAnswersSchema } from './agent-user-input'
7
+ import { objectRejectingKeys } from './rejected-keys'
5
8
 
6
9
  export const agentReasoningEffortSchema = z.enum(['low', 'medium', 'high', 'xhigh', 'max'])
7
10
  export const agentPromptModeSchema = z.enum(['next', 'steer'])
8
11
 
12
+ // A prompt may change the session's model and/or reasoning effort. The change takes effect where the
13
+ // prompt lands (a steer changes the running turn, a next-turn prompt the turn it starts) and stays
14
+ // the session's current settings afterwards. The model must belong to the session's provider.
15
+ export const agentSettingsChangeSchema = z.strictObject({
16
+ model: agentModelIdSchema.optional(),
17
+ reasoningEffort: agentReasoningEffortSchema.optional(),
18
+ }).refine(settings => settings.model !== undefined || settings.reasoningEffort !== undefined, {
19
+ message: 'A settings change needs a model or a reasoning effort.',
20
+ })
21
+
9
22
  export const agentAuthorSchema = z.object({
10
23
  name: z.string().min(1),
11
24
  email: z.string().min(1).optional(),
12
25
  gitEmail: z.string().min(1).optional(),
13
- }).strict()
26
+ })
14
27
 
15
28
  const commandIdSchema = z.string().min(1)
16
29
 
17
- const runningCommandBaseSchema = z.object({
30
+ // Provider turn identity never crosses this boundary; only the canonical turnId does.
31
+ const runningCommandBaseSchema = objectRejectingKeys({
18
32
  provider: agentProviderIdSchema,
19
33
  sessionId: z.string().min(1),
20
34
  providerSessionId: z.string().min(1),
21
- }).strict()
35
+ }, ['providerTurnId'])
22
36
 
23
37
  export const sendPromptCommandSchema = runningCommandBaseSchema.extend({
24
38
  type: z.literal('agent.send-prompt'),
25
39
  mode: agentPromptModeSchema,
40
+ turnId: z.string().min(1).optional(),
26
41
  origin: z.enum(['user', 'supervisor']).default('user'),
27
42
  prompt: agentPromptSchema,
28
43
  commandId: commandIdSchema,
29
44
  /** Resolved by the application for this prompt, including after runtime recovery. */
30
45
  model: z.string().trim().min(1).max(256).optional(),
46
+ reasoningEffort: agentReasoningEffortSchema.optional(),
31
47
  author: agentAuthorSchema.optional(),
32
- }).strict()
48
+ settings: agentSettingsChangeSchema.optional(),
49
+ })
50
+
51
+ export const agentNotifyCommandSchema = runningCommandBaseSchema.extend({
52
+ type: z.literal('agent.notify'),
53
+ commandId: commandIdSchema,
54
+ instruction: agentNotificationInstructionSchema.nullable(),
55
+ notifications: agentNotificationsSchema,
56
+ }).superRefine((command, context) => {
57
+ if (isAgentNotificationToolOutputWithinSizeLimit({
58
+ commandId: command.commandId,
59
+ instruction: command.instruction,
60
+ notifications: command.notifications,
61
+ })) {
62
+ return
63
+ }
64
+ context.addIssue({
65
+ code: 'custom',
66
+ path: ['notifications'],
67
+ message: 'Serialized notification tool output exceeds the allowed size.',
68
+ })
69
+ })
33
70
 
34
71
  export const interruptAgentCommandSchema = runningCommandBaseSchema.extend({
35
72
  type: z.literal('agent.interrupt'),
36
73
  commandId: commandIdSchema,
37
74
  turnId: z.string().min(1).optional(),
38
75
  reason: z.string().min(1).optional(),
39
- }).strict()
76
+ })
77
+
78
+ export const compactContextAgentCommandSchema = runningCommandBaseSchema.extend({
79
+ type: z.literal('agent.compact-context'),
80
+ commandId: commandIdSchema,
81
+ })
40
82
 
41
83
  export const stopAgentCommandSchema = runningCommandBaseSchema.extend({
42
84
  type: z.literal('agent.stop'),
43
85
  reason: z.string().min(1).optional(),
44
- }).strict()
86
+ })
45
87
 
46
88
  export const respondUserInputAgentCommandSchema = runningCommandBaseSchema.extend({
47
89
  type: z.literal('agent.respond-user-input'),
48
90
  commandId: commandIdSchema,
49
91
  requestId: z.string().min(1),
50
92
  answers: agentUserInputAnswersSchema,
51
- }).strict()
93
+ })
52
94
 
53
95
  export const agentCommandSchema = z.union([
54
96
  sendPromptCommandSchema,
97
+ agentNotifyCommandSchema,
55
98
  interruptAgentCommandSchema,
99
+ compactContextAgentCommandSchema,
56
100
  stopAgentCommandSchema,
57
101
  respondUserInputAgentCommandSchema,
58
102
  ])
59
103
 
60
104
  export type AgentReasoningEffort = z.infer<typeof agentReasoningEffortSchema>
61
105
  export type AgentPromptMode = z.infer<typeof agentPromptModeSchema>
106
+ export type AgentSettingsChange = z.infer<typeof agentSettingsChangeSchema>
62
107
  export type AgentAuthor = z.infer<typeof agentAuthorSchema>
63
108
  export type SendPromptCommand = z.infer<typeof sendPromptCommandSchema>
109
+ export type AgentNotifyCommand = z.infer<typeof agentNotifyCommandSchema>
64
110
  export type InterruptAgentCommand = z.infer<typeof interruptAgentCommandSchema>
111
+ export type CompactContextAgentCommand = z.infer<typeof compactContextAgentCommandSchema>
65
112
  export type StopAgentCommand = z.infer<typeof stopAgentCommandSchema>
66
113
  export type RespondUserInputAgentCommand = z.infer<typeof respondUserInputAgentCommandSchema>
67
114
  export type AgentCommand = z.infer<typeof agentCommandSchema>
@@ -1,54 +1,54 @@
1
1
  import z from 'zod'
2
2
 
3
- export const textAgentInputBlockSchema = z.object({
3
+ export const textAgentInputBlockSchema = z.strictObject({
4
4
  type: z.literal('text'),
5
5
  text: z.string(),
6
- }).strict()
6
+ })
7
7
 
8
- export const urlAgentImageSourceSchema = z.object({
8
+ export const urlAgentImageSourceSchema = z.strictObject({
9
9
  kind: z.literal('url'),
10
10
  url: z.url(),
11
- }).strict()
11
+ })
12
12
 
13
- export const base64AgentImageSourceSchema = z.object({
13
+ export const base64AgentImageSourceSchema = z.strictObject({
14
14
  kind: z.literal('base64'),
15
15
  data: z.string().min(1),
16
16
  mimeType: z.string().min(1),
17
- }).strict()
17
+ })
18
18
 
19
19
  export const agentImageSourceSchema = z.discriminatedUnion('kind', [
20
20
  urlAgentImageSourceSchema,
21
21
  base64AgentImageSourceSchema,
22
22
  ])
23
23
 
24
- export const imageAgentInputBlockSchema = z.object({
24
+ export const imageAgentInputBlockSchema = z.strictObject({
25
25
  type: z.literal('image'),
26
26
  source: agentImageSourceSchema,
27
- }).strict()
27
+ })
28
28
 
29
- export const textAgentFileSourceSchema = z.object({
29
+ export const textAgentFileSourceSchema = z.strictObject({
30
30
  kind: z.literal('text'),
31
31
  name: z.string().min(1).optional(),
32
32
  text: z.string(),
33
33
  mimeType: z.string().min(1).optional(),
34
- }).strict()
34
+ })
35
35
 
36
- export const urlAgentFileSourceSchema = z.object({
36
+ export const urlAgentFileSourceSchema = z.strictObject({
37
37
  kind: z.literal('url'),
38
38
  url: z.url(),
39
39
  name: z.string().min(1).optional(),
40
40
  mimeType: z.string().min(1).optional(),
41
- }).strict()
41
+ })
42
42
 
43
43
  export const agentFileSourceSchema = z.discriminatedUnion('kind', [
44
44
  textAgentFileSourceSchema,
45
45
  urlAgentFileSourceSchema,
46
46
  ])
47
47
 
48
- export const fileAgentInputBlockSchema = z.object({
48
+ export const fileAgentInputBlockSchema = z.strictObject({
49
49
  type: z.literal('file'),
50
50
  source: agentFileSourceSchema,
51
- }).strict()
51
+ })
52
52
 
53
53
  export const agentInputBlockSchema = z.discriminatedUnion('type', [
54
54
  textAgentInputBlockSchema,
@@ -56,9 +56,29 @@ export const agentInputBlockSchema = z.discriminatedUnion('type', [
56
56
  fileAgentInputBlockSchema,
57
57
  ])
58
58
 
59
+ const wireAgentImageSourceSchema = z.discriminatedUnion('kind', [
60
+ urlAgentImageSourceSchema.strip(),
61
+ base64AgentImageSourceSchema.strip(),
62
+ ])
63
+ const wireAgentFileSourceSchema = z.discriminatedUnion('kind', [
64
+ textAgentFileSourceSchema.strip(),
65
+ urlAgentFileSourceSchema.strip(),
66
+ ])
67
+ const wireAgentInputBlockSchema = z.discriminatedUnion('type', [
68
+ textAgentInputBlockSchema.strip(),
69
+ z.object({
70
+ type: z.literal('image'),
71
+ source: wireAgentImageSourceSchema,
72
+ }),
73
+ z.object({
74
+ type: z.literal('file'),
75
+ source: wireAgentFileSourceSchema,
76
+ }),
77
+ ])
78
+
59
79
  export const agentPromptSchema = z.object({
60
- blocks: z.array(agentInputBlockSchema).min(1),
61
- }).strict()
80
+ blocks: z.array(wireAgentInputBlockSchema).min(1),
81
+ })
62
82
 
63
83
  export type TextAgentInputBlock = z.infer<typeof textAgentInputBlockSchema>
64
84
  export type UrlAgentImageSource = z.infer<typeof urlAgentImageSourceSchema>