Skip to content
English

按已校验命令绑定本地 handler ​

策略的具体实现如下。

ts
export function bindInteraction<
  Value extends object,
  Parsed,
  Args extends unknown[],
  Id extends string,
  Context,
  Output,
>(
  protocol: {
    readonly commands: Pick<InteractionProtocol<Value, Parsed, Args, Id>['commands'], 'manifest'>;
    receive(value: Value, ...args: Args): { id: Id; result: Parsed };
  },
  handlers: InteractionHandlers<Id, Parsed, Context, Output>,
) {
  const catalog = Object.freeze(
    protocol.commands.manifest().map((command) =>
      Object.freeze({
        id: command.id,
        category: command.category,
        description: command.description,
        terminal: command.terminal,
        modes: command.modes && Object.freeze([...command.modes]),
      }),
    ),
  );
  const receive = protocol.receive.bind(protocol);
  const ids = new Set(catalog.map((command) => command.id));
  breakWhile(
    [
      {
        occur: () =>
          catalog.some(
            (command) =>
              typeof handlers[command.id as Id] !== 'function' ||
              (!Object.hasOwn(handlers, command.id) &&
                (command.id === 'constructor' ||
                  handlers[command.id as Id] === Reflect.get(Object.prototype, command.id))),
          ),
        error: 'Missing interaction handler',
        tags: ['missing-handler'],
      },
      {
        occur: () => Object.keys(handlers).some((id) => !ids.has(id)),
        error: 'Unregistered interaction handler',
        tags: ['unknown-handler'],
      },
    ],
    ['agent-core', 'interaction-registration'],
  );
  const registered = Object.freeze(
    Object.fromEntries(catalog.map(({ id }) => [id, handlers[id as Id].bind(handlers)])) as Record<
      Id,
      (value: Parsed, context: Context) => Output
    >,
  );
  return Object.freeze({
    catalog,
    dispatch(value: Value, context: Context, ...args: Args): Output {
      // Select from the validated wire value, never from a formatter's unconstrained output.
      const { id, result } = receive(value, ...args);
      return registered[id](result, context);
    },
  });
}

接口参考、使用示例与开发指南。