Skip to content

PHP converter support#5

Merged
MelbourneDeveloper merged 16 commits into
Nimblesite:phpfrom
voku:main
Apr 19, 2026
Merged

PHP converter support#5
MelbourneDeveloper merged 16 commits into
Nimblesite:phpfrom
voku:main

Conversation

@voku
Copy link
Copy Markdown
Contributor

@voku voku commented Apr 18, 2026

TLDR

Add support for php. 😊 🐘

Details

I just pasted some php examples into the chat and let codex do the rest.

How Do The Automated Tests Prove It Works?

I don't know why, but the fork of this project seems not to follow the coding agent instructions, maybe because @CLAUDE.md in the AGENTS.md is not working? Or because the instructions are too specific e.g. it says use "pino" but it seems that it isn't used at all for logging

@voku
Copy link
Copy Markdown
Contributor Author

voku commented Apr 18, 2026

Reviewed by my but written by Codex 5.4 so maybe not 100% correct
😊

@MelbourneDeveloper
Copy link
Copy Markdown
Collaborator

Thanks @voku . Got some failures in the CI script. Just run make CI to check what's going on. Also need some doco in the PR comments. Try running the /submit-pr skill to generate those

https://github.com/Nimblesite/typeDiagram/actions/runs/24597356276

Also, the sample in the convert page is a bit broken. Here's the corrected code:

const SAMPLES: Record<SupportedLang, string> = {
  typescript: `export interface ChatRequest {
  message: string;
  session_id: string;
  tool_results: Array<ToolResult>;
}

export interface ChatTurnInput {
  config: AgentConfig;
  user_message: string;
  tool_results: Array<ToolResult>;
  session_id: string;
}

export interface ToolResult {
  tool_call_id: string;
  name: string;
  content: string;
  ok: boolean;
}

export interface TextPart {
  text: string;
}

export interface UriPart {
  url: string;
  kind: UriKind;
  media_type: string;
}

export type ContentItem =
  | { kind: "Text"; value: TextPart }
  | { kind: "Uri"; value: UriPart }
  | { kind: "Scalar"; value: string };

export type UriKind =
  | { kind: "Image" }
  | { kind: "Audio" }
  | { kind: "Video" }
  | { kind: "Document" }
  | { kind: "Web" }
  | { kind: "Api" };
`,
  rust: `pub struct ChatRequest {
    pub message: String,
    pub session_id: String,
    pub tool_results: Option<Vec<ToolResult>>,
}

pub struct ChatTurnInput {
    pub config: AgentConfig,
    pub user_message: String,
    pub tool_results: Option<Vec<ToolResult>>,
    pub session_id: String,
}

pub struct ToolResult {
    pub tool_call_id: String,
    pub name: String,
    pub content: String,
    pub ok: bool,
}

pub struct TextPart {
    pub text: String,
}

pub struct UriPart {
    pub url: String,
    pub kind: UriKind,
    pub media_type: Option<String>,
}

pub enum ContentItem {
    Text { value: TextPart },
    Uri { value: UriPart },
    Scalar { value: String },
}

pub enum UriKind {
    Image,
    Audio,
    Video,
    Document,
    Web,
    Api,
}
`,
  python: `from dataclasses import dataclass

@dataclass
class ChatRequest:
    message: str
    session_id: str
    tool_results: Optional[list[ToolResult]]

@dataclass
class ChatTurnInput:
    config: AgentConfig
    user_message: str
    tool_results: Optional[list[ToolResult]]
    session_id: str

@dataclass
class ToolResult:
    tool_call_id: str
    name: str
    content: str
    ok: bool

@dataclass
class TextPart:
    text: str

@dataclass
class UriPart:
    url: str
    kind: UriKind
    media_type: Optional[str]
`,
  go: `type ChatRequest struct {
	Message     string
	SessionID   string
	ToolResults []ToolResult
}

type ChatTurnInput struct {
	Config      AgentConfig
	UserMessage string
	ToolResults []ToolResult
	SessionID   string
}

type ToolResult struct {
	ToolCallID string
	Name       string
	Content    string
	Ok         bool
}

type TextPart struct {
	Text string
}

type UriPart struct {
	Url       string
	Kind      UriKind
	MediaType *string
}

type ContentItem interface {
	Text
	Uri
	Scalar
}

type UriKind interface {
	Image
	Audio
	Video
	Document
	Web
	Api
}
`,
  csharp: `public record ChatRequest(
    string Message,
    string SessionId,
    List<ToolResult>? ToolResults
);

public record ChatTurnInput(
    AgentConfig Config,
    string UserMessage,
    List<ToolResult>? ToolResults,
    string SessionId
);

public record ToolResult(
    string ToolCallId,
    string Name,
    string Content,
    bool Ok
);

public record TextPart(
    string Text
);

public record UriPart(
    string Url,
    UriKind Kind,
    string? MediaType
);

public enum ContentItem {
    Text,
    Uri,
    Scalar
}

public enum UriKind {
    Image,
    Audio,
    Video,
    Document,
    Web,
    Api
}
`,
  fsharp: `type ChatRequest = {
    message: string
    session_id: string
    tool_results: ToolResult list option
}

type ChatTurnInput = {
    config: AgentConfig
    user_message: string
    tool_results: ToolResult list option
    session_id: string
}

type ToolResult = {
    tool_call_id: string
    name: string
    content: string
    ok: bool
}

type TextPart = {
    text: string
}

type UriPart = {
    url: string
    kind: UriKind
    media_type: string option
}

type ContentItem =
    | Text of value: TextPart
    | Uri of value: UriPart
    | Scalar of value: string

type UriKind =
    | Image
    | Audio
    | Video
    | Document
    | Web
    | Api
`,
  php: `<?php

declare(strict_types=1);

final readonly class ChatRequest
{
    /**
     * @param list<ToolResult>|null $tool_results
     */
    public function __construct(
        public string $message,
        public string $session_id,
        public ?array $tool_results = null,
    ) {}
}

final readonly class ChatTurnInput
{
    /**
     * @param list<ToolResult>|null $tool_results
     */
    public function __construct(
        public AgentConfig $config,
        public string $user_message,
        public string $session_id,
        public ?array $tool_results = null,
    ) {}
}

final readonly class ToolResult
{
    public function __construct(
        public string $tool_call_id,
        public string $name,
        public string $content,
        public bool $ok,
    ) {}
}

final readonly class TextPart
{
    public function __construct(
        public string $text,
    ) {}
}

final readonly class UriPart
{
    public function __construct(
        public string $url,
        public UriKind $kind,
        public ?string $media_type = null,
    ) {}
}

interface ContentItem
{
}

final readonly class Text implements ContentItem
{
    /** @var 'Text' */
    public string $kind;

    public function __construct(
        public TextPart $value,
    )
    {
        $this->kind = 'Text';
    }
}

final readonly class Uri implements ContentItem
{
    /** @var 'Uri' */
    public string $kind;

    public function __construct(
        public UriPart $value,
    )
    {
        $this->kind = 'Uri';
    }
}

final readonly class Scalar implements ContentItem
{
    /** @var 'Scalar' */
    public string $kind;

    public function __construct(
        public string $value,
    )
    {
        $this->kind = 'Scalar';
    }
}

interface UriKind
{
}

final readonly class Image implements UriKind
{
    /** @var 'Image' */
    public string $kind;

    public function __construct()
    {
        $this->kind = 'Image';
    }
}

final readonly class Audio implements UriKind
{
    /** @var 'Audio' */
    public string $kind;

    public function __construct()
    {
        $this->kind = 'Audio';
    }
}

final readonly class Video implements UriKind
{
    /** @var 'Video' */
    public string $kind;

    public function __construct()
    {
        $this->kind = 'Video';
    }
}

final readonly class Document implements UriKind
{
    /** @var 'Document' */
    public string $kind;

    public function __construct()
    {
        $this->kind = 'Document';
    }
}

final readonly class Web implements UriKind
{
    /** @var 'Web' */
    public string $kind;

    public function __construct()
    {
        $this->kind = 'Web';
    }
}

final readonly class Api implements UriKind
{
    /** @var 'Api' */
    public string $kind;

    public function __construct()
    {
        $this->kind = 'Api';
    }
}
`,
};

voku and others added 10 commits April 18, 2026 13:41
Agent-Logs-Url: https://github.com/voku/typeDiagram/sessions/e2e17a2e-7bc6-4a33-8d6a-4150cbd90751

Co-authored-by: voku <264695+voku@users.noreply.github.com>
Fix PHP converter CI: unhandled rejection, coverage threshold, bundle budget
Fix web converter samples and clear CI lint noise
@voku
Copy link
Copy Markdown
Contributor Author

voku commented Apr 18, 2026

@MelbourneDeveloper CI should be "green" now 🤞 and the example / README is updated

@MelbourneDeveloper
Copy link
Copy Markdown
Collaborator

Please update the PR description @voku

Copy link
Copy Markdown
Collaborator

@MelbourneDeveloper MelbourneDeveloper left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The original converter samples were a mess and I've cleaned them up now, but that's resulted in merge conflicts. We will just accept this PR, but we will need to clean it up in a branch before merging to main

@MelbourneDeveloper MelbourneDeveloper changed the base branch from main to php April 19, 2026 06:38
@MelbourneDeveloper MelbourneDeveloper deleted the branch Nimblesite:php April 19, 2026 06:40
@MelbourneDeveloper MelbourneDeveloper merged commit bb3e86f into Nimblesite:php Apr 19, 2026
2 checks passed
@MelbourneDeveloper
Copy link
Copy Markdown
Collaborator

MelbourneDeveloper commented Apr 19, 2026

This work in this PR eventually ended up in this PR:
#18

But it required a fair bit a massaging. thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants